Ранее уже пробовал запускать GPS-модуль GY-NEO6MV2 и получать с него данные, а тут одним подписчиком вновь была поднята эта интересная тема в направлении того, чтобы с помощью этого модуля делать синхронизацию времени на часах Часы на RTC DS3231, с расширенными функциями v3.x. Подумалось, а почему бы сразу не сделать сверхточные часы, у которых не нужно корректировать время. В итоге получился интересный проект. Смотрите далее.
GPS является аббревиатурой, т.е. расшифровывается как: Global Position System. GPS-модуль предназначен для получения сигналов позиционирования со спутников, которые летают над Землёй. Связь, само-собой, осуществляется в одном направлении – на приём. Поэтому при подключении модуля к Ардуино достаточно подключить вывод Tx модуля с Rx Ардуино. Так как само Ардуино использует последовательный порт Rx/Tx для связи с компьютером, то необходимо для GPS-модуля создать последовательный порт, который бы использовал иные контакты, отличные от 0(Rx)/1(Tx). Для этого можно воспользоваться функцией библиотеки SoftwareSerial. Используя эту библиотеку можно назначить любые выводы под Rx/Tx. В моей программе они назначены на RX_pin = 10, TX_pin = 11. Скорость передачи данных с модуля по умолчанию: 9600 бод. Поэтому в скетче устанавливаем такое же значение при инициализации программного последовательного порта.
По последовательному порту с приёмника GPS-модуля поступают текстовые символы, поля которых отделены запятыми. В конце строки стоит завершающий символ перевода строки. Формат сообщений соответствует стандарту NMEA – National Marine Electronics Association. Несколько подробнее этот формат описан ниже в начале скетча. Отмечу лишь, что посылка с основными данными начинается с кодового слова $GPRMC, поэтому декодировать будем ту сторку, которая имеет вначале это слово.
Для вывода информации, использую популярный и недорогой дисплей Nokia-5110/3310, для разнообразия, а то лежит место занимает , конечно можно использовать любой другой дисплей, можно и цветной, или монохромный.
GY-NEO6MV2 Arduino Nano
VCC +5V
GND GND
TX 10
RX не используется
Nokia-5110 R Arduino Nano
RST 3
CS 4
DC 5
DIN 6
CLK 7
BL -[2R2]- 9~ Подсветка
Выход синхонизации
Arduino R PS817
А0 -[510 Ом]- 1
GND - 2
Схема модуля GPS-модуля GY-NEO6MV2 ниже.
ПОЯСНЕНИЯ
На дисплее Nokia-5110 выводятся:
Режим экрана 1:
Время с учётом поясного времени (изменение в настройках)
Дата в международном формате: ГГГГ-ММ-ДД
Если GPS поймал нужное чило спутников, то дополнительно
выводится:
Широта Север/Юг
Долгота Восток/Запад
Режим экрана 2:
Время с учётом поясного времени (изменение в настройках)
Дата в международном формате: ГГГГ-ММ-ДД
Если спутники вообще не обнаружены, то на дисплее выводится значение поясной поправки времени и надпись No signal(Нет сигнала).
Если спутники обнаружены, но их недостаточно для определения координат, то на дисплее выводится только время и дата. При дальнейшем обнаружении достаточного количества спутников, на дисплей начинают выводится и координаты: Широта/Долгота.
Для управления часами имеется три кнопки управления:
SET - долгое нажатие вход/выход в/из меню настройки.
SET - короткое нажатие - переход к следующему параметру.
PLUS - Прибавить значение.
MINUS - Убавить значение.
Пункт, который может изменятся, отмечен курсором >. На экране помещаются не все пункты меню. Когда курсор доходит до низа экрана и далее нажатие на кнопку SET производит прокрутку пунктов и в нижней строке появляется очередной пункт меню.
Реализована и функция синхронизации любых внешних устройств (часов и т.п.).
Работает следующим образом:
При смене часа на выводе PIN_CORR (A0) выдаётся импульс коррекции. Настройка длительности в меню настроек. Если установлена длительность 0 мс, то импульс не выдаётся. Для управления внешними устройствами рекомендуется к выводу PIN_CORR подключить резистор 510 Ом, который соединить с выводом 1 оптрона PC817.
Вывод 2 оптрона PC817 соединить с GND. Выводы 3, 4 - выход управления на внешнее устройство. Оптическая развязка разделить цепь питания часов от цепи питания внешних устройств.
Скетч
В скетче применена условная компиляция для возможности отладки работы программы. Если убрать комментарии на определение SIMULAR (строка 106), то вместо реальной посылки с GPS-модуля будут подставлены тестовые посылки, по которым можно отладить вывод на дисплей (строки 213-223). Не стал убирать для тех, кто будет использовать какие-то другие дисплей, отличные от Nokia-5110, и ему понадобится отладить вывод на дисплей.
На мой взгляд ещё в скетче интересна реализация меню настроек. Заходить в него и выходить из него через долгое нажатие кнопки SET. Есть возможность настраивать всё. Если нужно добавить пункт-другой, то это легко сделать дописав в структуре меню соответствующие строки.
Ниже представлен скетч часов на основе GPS-модуля. Файл со скетчем можно скачать в подразделе Приложение.
/****************************************************************
GPS часы. Идея проекта взята тут:
https://microkontroller.ru/arduino-projects/
gps-chasy-na-arduino-uno/
*****************************************************************
ОПИСАНИЕ протокола с GPS:
Строка $GPRMC содержит скорость, время, дату и местоположение:
$GPRMC,123519.000,A,7791.0381,N,06727.4434,E,
022.4,084.4,230394,003.1,W*6A
$GPRMC,HHMMSS.SSS,A,latitude,N,longitude,E,
speed,angle,date,MV,W,CMD
Идентификатор Описание
RMC Recommended Minimum sentence C
HHMMSS.SSS Время в формате: ЧасМинутаСекунда.миллисекунда
A Статус:
A=active (активный)
V= void (пустой, недействительный) при потери
спутников
Latitude Широта (координата) умноженная на 100
N Направление: N=North (север), S=South (юг)
Longitude Долгота (координата) умноженная на 100
E Направление: E= East (восток), W=West (запад)
Speed Скорость в узлах (1 узел= 1,87 км в час)
Angle Угол места в градусах
Date Временная отметка:
дата в UTC,
Universal Time Coordinated —
всеобщее скоорд. время
MV Магнитное возмущение
W Direction of variation E/W
(направление изменения E/W)
CMD (*6A) Данные контрольной суммы
ПРИМЕЧАНИЕ
Полный список сообщений NMEA GPS можно найти
по адресу http://aprs.gids.nl&/nmea/
**************************************************************
https://www.mralb.ru/sections/programming/arduino_35.php
2024-04-07 Mr.ALB v1.0 дисплей Nokia-5110 вывод даты и времени
2024-04-09 Mr.ALB v1.1 Вывод координат + меню настроек
МЕНЮ настроек:
кнопка SET - долгое нажатие вход/выход в/из меню настроек
кнопка SET - краткое нажатие в меню - перебор параметра
кнопка PLUS - увеличить значение
кнопка MINUS - уменьшить значение
2024-04-09 Mr.ALB v1.2 Реализация корректирующего импульса
Корректирующий сигнал для внешних часов
на выводе PIN_CORR при смене часа выдаёт
импульс длительностью param.v[5]
2024-04-12 Mr.ALB v1.3 Переделка меню настроек
2024-04-13 Mr.ALB v1.4 Добавлены режимы экрана:
часы/дата
все параметры
2024-04-13 Mr.ALB v1.5 Функции вывода даты/времени
ПОЯСНЕНИЯ:
На дисплее Nokia5110 выводятся:
Время с учётом поясного времени (изменение в настройках)
Дата в международном формате: ГГГГ-ММ-ДД
Если GPS поймал нужное чило спутников, то дополнительно
выводится:
Широта Север/Юг
Долгота Восток/Запад
Три кнопки управления:
SET - долгое нажатие вход/выход в/из меню настройки
SET - короткое нажатие - переход к следующему параметру
PLUS - Прибавить значение
MINUS - Убавить значение
При смене часа на выводе PIN_CORR выдаётся импульс
коррекции для любых внешних устройств (часов и т.п.).
Настройка длительности в меню настроек. Если установлена
длительность 0 мс, то импульс не выдаётся.
Для управления внешними устройствами рекомендуется к
выводу PIN_CORR подключить резистор 510 Ом, который
соединить с выводом 1 оптрона PC817.
Вывод 2 оптрона PC817 соединить с GND.
Выводы 3, 4 - выход управления на внешнее устройство.
GY-NEO6MV2 Arduino Nano
VCC +5V
GND GND
TX 10
RX не используется
Nokia-5110 R Arduino Nano
RST 3
CS 4
DC 5
DIN 6
CLK 7
BL -[2R2]- 9~ Подсветка
Выход синхонизации
Arduino R PS817
А0 -[510 Ом]- 1
GND - 2
Скетч использует 14880 байт (48%) памяти устройства
**************************************************************/#include<avr/pgmspace.h>#include<LCD5110_Basic.h>// Подключение библиотеки LCD5110//#define SIMULAR // Симуляция GPS//#define DEBUG // Для отладкиconstString title ="GPS-clock v1.5"; // Заголовок экрана// Типы используемых Ардуино#define ARDUINO_UNO 1
#define ARDUINO_NANO 2
#define ARDUINO_PROMINI 3
// Тип используемого Ардуино#define ARDUINO_TYPE ARDUINO_NANO
// Дисплей 1#define PIN_RST 3
#define PIN_CS 4 // индивидуально!#define PIN_DC 5
#define PIN_DIN 6
#define PIN_CLK 7
#define PIN_BL 9 // Подсветка на pin~ через резистор 2R2 //#define LCD_BLUE_1//#define LCD_BLUE_2//#define LCD_RED_1#define LCD_RED_2
#ifdef LCD_BLUE_1
byte contrast = 50;
#endif#ifdef LCD_BLUE_2
byte contrast = 60;
#endif#ifdef LCD_RED_2
byte contrast = 55;
#endif#ifdef LCD_RED_1
byte contrast = 70;
#endif#define KNP_MENU 2
#define KNP_MINUS 8
#define KNP_PLUS 12
#define PIN_CORR A0
#define KNP_WAIT 90
#define TIME_WAIT 1500
#define MAX_PARAM 6
// Структура параметров менюstruct
{
// Название пунктаString nom[MAX_PARAM] =
{
"Contrast",// Контраст дисплея"Mode",// Режим экрана"Light",// Яркость подсветки 0...255"OffsetH",// Часовой пояс - часы"OffsetM",// Часовой пояс - минуты"TimCorr",// Корректирующий импульс - мс
};
// Значение пунктаint v[MAX_PARAM] =// Массив параметров
{
contrast,// 0 Контраст дисплея
1,// 1 Режим экрана
125,// 2 Яркость подсветки
4,// 3 Часовой пояс Самары +4 часа
0,// 4 Часовой пояс Самары +0 минут
500,// 5 Длительность корр.импульса
};
// Ограничение значения снизуintmin[MAX_PARAM] =// Нижний предел параметра
{
0,
1,
0,-12,-59,
0,
};
// Ограничение значения сверхуintmax[MAX_PARAM] =// Верхний предел параметра
{
120,
2,
250,
12,
59,
2000,
};
} param;
// Создадим объект дисплеяLCD5110 lcd (PIN_CLK, PIN_DIN, PIN_DC, PIN_RST, PIN_CS);
externuint8_t SmallFont[]; // Основной шрифт - английскийexternuint8_t MediumNumbers[]; // Средние цифры// Программный последовательный порт#include<SoftwareSerial.h>SoftwareSerialSerial1(10, 11); // RX, TX#ifdef SIMULAR
// Симуляция сигналов GPS приёмника для отладки
// Статус: Активный - достаточно спутников
//char str[70] = "$GPRMC,123519.000,A,15328.0381,N,06727.4434,
// E,022.4,084.4,130424,003.1,W*6A";
// Статус: Пустой - недостаточно спутников
//char str[70] = "$GPRMC,103914.00,V,,,,,,,130424,,,N*73";
// Статус: Нет сигналаchar str[70] ="";
#elsechar str[70];
#endifchar*test ="$GPRMC"; // Заголовок посылки от GPSbyte temp, i;
// Переменные даты/времениint Hour,
Minut,
Second,
Date,
Month,
Year;
// Предыдущие значения даты и времениint preDate,
preMonth,
preYear,
preHour,
preMinut;
// Предыдущее значение координатfloat preLat,
preLng;
long time_push; // Время нажатия кнопкиconstbyte xcurs = 9 * 6; // позиция курсора
/**********************************
Функция настройки
*********************************/voidsetup()
{
#ifdef DEBUG
Serial.begin(9600);
#endif// Инициализация дисплея
lcd.InitLCD(param.v[0]); // Указание на контраст [0...127]
lcd.disableSleep(); // Пробуждение дисплея
lcd.clrScr(); // Стирание экранаpinMode(PIN_BL,OUTPUT); // Пин подсветки дисплеяanalogWrite(PIN_BL, param.v[2]); // Яркость подсветки 0...255pinMode(KNP_MENU,INPUT_PULLUP); // Кнопка менюpinMode(KNP_MINUS,INPUT_PULLUP); // Кнопка МинусpinMode(KNP_PLUS,INPUT_PULLUP); // Кнопка ПлюсpinMode(LED_BUILTIN,OUTPUT); // PIN13 - Сигнал коррекцииdigitalWrite(LED_BUILTIN,LOW);
pinMode(PIN_CORR,OUTPUT); // Выход корректирующего сигналаdigitalWrite(PIN_CORR,LOW); // ВыключимSerial1.begin(9600); // Программный порт
lcd.setFont(SmallFont); // Шрифт
lcd.print(title,CENTER, 0); // Заголовокdelay(300);
} // end setup()/***********************************
Основная функция
**********************************/byte mode;
voidloop()
{
#ifdef SIMULAR
temp = 1; // Симуляция GPS#else
fnSerial1Event(); // Получение сигнала с GPS#endif/***********************************
Переход в меню настроек
***********************************/if (!digitalRead(KNP_MENU))
{
time_push =millis();
delay(KNP_WAIT); // Задержка от дребезга кнопки// Ожидаем пока кнопка нажатаwhile (!digitalRead(KNP_MENU));
// Проверка времени нажатия кнопкиif ((millis() - time_push) >= TIME_WAIT)
{
// Если нажатие больше TIME_WAIT,
// Выводим меню с параметрами
lcd.clrScr(); // Очистка экрана
lcd.print("Settings",CENTER, 0); // Заголовокbyte sch = 0; // Счётчик пунктов меню
fnPrintMenu(0); // Выведем все пункты меню
lcd.print(">", xcurs, 8); // Маркер на первый пунктwhile (1) // Безконечный цикл перебора пунктов меню
{
if (!digitalRead(KNP_MENU))
{
time_push =millis();
delay(KNP_WAIT); // Задержка от дребезга кнопки// Ожидаем пока кнопка нажатаwhile (!digitalRead(KNP_MENU));
// Проверка длительности нажатияif ((millis() - time_push) >= TIME_WAIT)
{ // Если долгое нажатие
lcd.clrScr();
lcd.print(title,CENTER, 0);
break; // Выход из меню
}
//***************************************
// Если короткое нажатие
fnPrintMenu(sch); // Выведем все пункты меню// Стираем маркер
lcd.clrRow( ((sch > 4) ? 5 : sch + 1), xcurs , xcurs + 6);
sch++; // Переход к следующему пунктуif (sch > 4) fnPrintMenu(sch);
if (sch > MAX_PARAM - 1)
{
sch = 0;
fnPrintMenu(sch);
}
// Маркер на значение пункта меню
lcd.print(">", xcurs, ((sch > 4) ? 5 : sch + 1) * 8);
}
// Изменение параметра пунктаif (!digitalRead(KNP_MINUS)) // Убавить
{
delay(KNP_WAIT);
// Другое приращение при измененииif (sch == 1 || sch == 3 || sch == 4)
param.v[sch]--;
else
param.v[sch] -= 5;
if (param.v[sch] < param.min[sch])
param.v[sch] = param.min[sch];
}
if (!digitalRead(KNP_PLUS)) // Прибавить
{
delay(KNP_WAIT);
// Другое приращение при измененииif (sch == 1 || sch == 3 || sch == 4)
param.v[sch]++;
else
param.v[sch] += 5;
// Проверка границif (param.v[sch] > param.max[sch])
param.v[sch] = param.max[sch];
}
// Очистим место под значение
lcd.clrRow(((sch > 4) ? 5 : sch + 1), xcurs + 6);
lcd.printNumI(param.v[sch], xcurs + 6,
((sch > 4) ? 5 : sch + 1) * 8);
// Команды на текущее выполнениеswitch (sch)
{
case 0:// Новый контраст
lcd.setContrast(param.v[sch]);
break;
case 2:// Новая яркость подсветки дисплея#ifdef LCD_RED_2
// Странный дисплей.
// При увеличении яркость уменьшаетсяanalogWrite(PIN_BL, 255 - param.v[sch]);
#else// Нормальный дисплейanalogWrite(PIN_BL, param.v[sch]);
#endifbreak;
case 5:
preMinut = Minut - 1;
}
delay(KNP_WAIT);
} // end while(1)
}
// Для восстановления вывода значений
preHour--;
preMinut--;
preYear--;
preMonth--;
preDate--;
} // end menu settings/****************************************
Обработка данных с GPS приёмника
***************************************/
// Если получены данные с GPS приёмникаif (temp)
{
#ifdef SIMULAR
int str_lenth = 64; // Симуляция GPS#elseint str_lenth = i;
#endif#ifdef DEBUG
for (byte i = 0; i < str_lenth; i++)
{
Serial.print(str[i]);
}
Serial.println();
#endifint x = 0, comma = 0;
// Параметры даты и времениString UTC_hour ="";
String UTC_minut ="";
String UTC_second ="";
String UTC_date ="";
String UTC_month ="";
String UTC_year ="";
// Координаты положенияString LatDegree ="";
String LatDir ="";
String LngDegree ="";
String LngtDir ="";
String str1 ="";
while (x < str_lenth)
{
// Поиск разделителяif (str[x] ==',')
comma++;
// Времяif (comma == 1)
{
x++;
UTC_hour += str[x++];
UTC_hour += str[x++];
UTC_minut += str[x++];
UTC_minut += str[x++];
UTC_second += str[x++];
UTC_second += str[x];
comma = 2;
}
// Широта в градусах * 100if (comma == 4)
{
x++;
while (str[x] !=',')
{
LatDegree += str[x++];
}
comma = 5;
}
// Полушарие Северное/Южное N/Sif (comma == 5)
{
x++;
while (str[x] !=',')
{
LatDir += str[x++];
}
comma = 6;
}
// Долгота в градусах * 100if (comma == 6)
{
x++;
while (str[x] !=',')
{
LngDegree += str[x++];
}
comma = 7;
}
// Направление Восток/Запад E/Wif (comma == 7)
{
x++;
while (str[x] !=',')
{
LngtDir += str[x++];
}
comma = 8;
}
// Датаif (comma == 10)
{
x++;
UTC_date += str[x++];
UTC_date += str[x++];
UTC_month += str[x++];
UTC_month += str[x++];
UTC_year += str[x++];
UTC_year += str[x];
}
x++;
}
// Преобразуем строки с данными в значенияint UTC_hourDec = UTC_hour.toInt();
int UTC_minutDec = UTC_minut.toInt();
Second = UTC_second.toInt();
Date = UTC_date.toInt();
Month = UTC_month.toInt();
Year = UTC_year.toInt();
float Lat = LatDegree.toFloat() / 100;
float Lng = LngDegree.toFloat() / 100;
#ifdef DEBUG
Serial.print("Latitude: ");
Serial.print(LatDegree);
Serial.print("\t ");
Serial.print(Lat, 4);
Serial.println(LatDir);
#endif// Учитываем часовой пояс в часах
Hour = UTC_hourDec + param.v[3];
if (Hour > 23)
{
Hour -= 24;
Date += 1;
}
// Учитываем часовой пояс в минутах
Minut = UTC_minutDec + param.v[4];
if (Minut > 59)
Minut -= 60;
/****************************
Вывод значений на дисплей
***************************/
// Часbyte row = 2;
byte col = 6 * 6;
// Корректирующий сигнал для внешних часов
// на выводе PIN_CORR при смене часа выдаёт
// импульс длительностью param.v[5] в мсif (Hour != preHour && Minut == 0 && param.v[5] != 0)
{
digitalWrite(PIN_CORR,HIGH);
delay(param.v[5]);
digitalWrite(PIN_CORR,LOW);
// Индикация импульса коррекцииdigitalWrite(LED_BUILTIN,HIGH);
delay(1000);
digitalWrite(LED_BUILTIN,LOW);
}
switch (param.v[1])
{
case 1:// Режим: вся информация
fnPrintTime(2,true); // Выводим время#ifdef DEBUG
Serial.print("Year=");
Serial.print(Year);
Serial.print("\tpreYear=");
Serial.println(preYear);
Serial.print("mode=");
Serial.print(mode);
Serial.print("\tparam.v[1]=");
Serial.println(param.v[1]);
#endif
fnPrintDate(4, 3,true); // Выводим дату// Широтаif (Lat != 0 && Lat != preLat)
{
row = 4 * 8;
col = 4 * 6;
lcd.print("La:", 0, row);
if (Lat >= 100)col -= 6;
lcd.printNumF(Lat, 6, col, row);
lcd.print(LatDir, 13 * 6, row);
}
// Долготаif (Lng != 0 && Lng != preLng)
{
row = 5 * 8;
col = 4 * 6;
lcd.print("Ln:", 0, row);
if (Lng >= 100)col -= 6;
lcd.printNumF(Lng, 6, col, row);
lcd.print(LngtDir, 13 * 6, row);
}
// Секунды
col = 12 * 6;
row = 16;
mode = param.v[1];
break;
case 2:// Режим: часы/дата// Выводим время
fnPrintTime(1,false);
// Выводим дату
lcd.setFont(SmallFont); // Шрифт
fnPrintDate(4, 5,false);
// Секунды
col = 12 * 6;
row = 24;
mode = param.v[1];
}
// Секунды
lcd.print(":", 11 * 6, row);
if (Second < 10)
{
lcd.print("0", col, row);
col += 6;
}
lcd.printNumI(Second, col, row);
delay(50);
// Обновление начальных значений
preDate = Date;
preMonth = Month;
preYear = Year;
preHour = Hour;
preMinut = Minut;
preLat = Lat;
preLng = Lng;
temp = 0;
i = 0;
x = 0;
str_lenth = 0;
}
} // end loop()/********************************************
Функция: Получение данных с GPS приёмника
********************************************/void fnSerial1Event()
{
while (1)
{ // Проверка наличия данных от GPS
// по каналу последовательной связиwhile (Serial1.available())
{
// Читаем символ из портаchar inChar = (char)Serial1.read();
// Сохраняем данные от GPS в массиве str[]
str[i] = inChar;
i++;
if (i < 7)
{
// Проверка на заголовок данных: $GPRMCif (str[i - 1] != test[i - 1])
i = 0;
}
// Конец посылкиif (i > 65)
{
temp = 1;
break; // Выход из while(Serial1.available())
}
}
if (temp)
break; // Выход из while(1)
}
}
/****************************************************
Функция: Вывод пунктов меню на экран
2024-04-12 Mr.ALB v1.0
***************************************************/void fnPrintMenu(byte curs)
{
byte p = 0;
if (curs > 4) p += curs - 4;
for (byte i = 0; i <= 5; i++)
{
// Очистим строку
lcd.clrRow(i + 1, 0);
// Название параметра
lcd.print(param.nom[p], 0, (i + 1) * 8);
// Значение параметра
lcd.printNumI(param.v[p++], xcurs + 6, (i + 1) * 8);
if (p > MAX_PARAM - 1)break;
}
}
/***************************************************
Функция: Вывод даты
**************************************************/void fnPrintDate(byte cl,byte rw,bool flag)
{
rw = rw * 8;
byte col;
// Если есть сигнал, то год != 0 и выводимif (Year != 0)
{
// Год изменился или изменился режим экранаif (Year != preYear || mode != param.v[1])
{
// Очистка от фразы "No signal"
lcd.print(" ",CENTER, rw);
if (flag)
lcd.print("Dat:20", 0, rw);
col = cl * 6;
lcd.print("20", col, rw);
lcd.printNumI(Year, col + 12, rw);
}
// Месяц изменился или изменился режим экранаif (Month != preMonth || mode != param.v[1])
{
col = (cl + 4) * 6;
lcd.print("-", col, rw);
col += 6;
if (Month < 10)
{
lcd.print("0", col, rw);
col += 6;
}
lcd.printNumI(Month, col, rw);
}
// День изменился или изменился режим экранаif (Date != preDate || mode != param.v[1])
{
col = (cl + 7) * 6;
lcd.print("-", col, rw);
col += 6;
if (Date < 10)
{
lcd.print("0", col, rw);
col += 6;
}
lcd.printNumI(Date, col, rw);
}
}
else
{
if (mode != param.v[1])
{
lcd.clrRow(rw * .125, 0);
lcd.print("No signal",CENTER, rw);
}
}
}
/************************************************
Функция: Вывод времени
2024-04-13 Mr.ALB
аргументы:
rw - ряд 0...5
flag - если
true - SmallFont
false - MediumNumbers
***********************************************/void fnPrintTime(byte rw,bool flag)
{
byte row, col;
if (flag)
{
lcd.setFont(SmallFont); // Шрифт
col = 6 * 6;
row = rw * 8;
}
else
{
lcd.setFont(MediumNumbers); // Шрифт
col = 6;
row = rw * 16;
}
if (Hour != preHour || mode != param.v[1])
{
if (flag)
lcd.print("Time:", 0, row);
if (Hour < 10)
col += (flag) ? 6 : 12;
lcd.printNumI(Hour, col, row);
}
// Минутыif (Minut != preMinut || mode != param.v[1])
{
if (flag)
col = 8 * 6;
else
col = 30;
lcd.print(":", col , row);
col += (flag) ? 6 : 12;
if (Minut < 10)
{
lcd.print("0", col, row);
col += (flag) ? 6 : 12;
}
lcd.printNumI(Minut, col, row);
}
}
Реализация
Для проверки работоспособности GPS-модуля использовал Arduino Nano. Можно использовать любое. На контакт VCC дисплея подаю +5 В. Контакты дисплея используемые для SPI пробовал подключать через сопротивления 1.2 кОм, но и без них вполне нормально работает. Для удобства макетирования использую плату расширения под Arduino Nano.
В первом варианте скетча на дисплей выводились координаты с 4-ю знаками после запятой, в последующих вариантах вывожу уже по 6 знаков после запятой.
Чтобы устранить помехи, подключил параллельно питанию Ардуино два конденсатора: на 0.1 мкФ, и на 470 мкФ 6.3 В. Ниже на фото видно, что на дисплее выводятся только время и дата, что означает недостаточное количество видимых спутников.
GPS-часы
Продолжительность фильма 0:27 [мм:сс]
Светодиод на GPS-модуле мигает, что указывает на достаточное количество видимых спутников для получения полной информации: время, дата, широта (Latitude), долгота (Longitude).
2024-04-14
Этот проект более совершенный, чем предыдущий. Как будет время, то можно сделать законченную конструкцию в виде небольшого блока.
Если вы будете повторять этот проект, то обратите внимание, что на GPS-модуле GY-NEO6MV2 есть красный светодиодик. Если он не светится и не мигает, то значит ваш модуль не обнаружил достаточное количество спутников и данные поступают неверные. Ещё может быть, что батарейка хранения данных в EEPROM модуля разрядилась, требуется какое-то время, пока она не подзарядится.
Заметил у себя, что когда недостаточно спутников, то в посылке поля с координатами пустые, а вот время и дата заполнены, поэтому на дисплей выводится только дата и время.