Задумал я собрать часы, которые не нуждались бы в настройке (подводке). Было два варианта реализации с помощью модуля часов DS3231 и с помощью GPS модуля VK2828U7G5LF. Был ещё вариант использовать оба модуля, но это показалось мне излишним. В общем остановился на GPS модуле.
Основное окно
Второе окно
Далее представлен код для ардуино с пояснениями.
#include <TinyGPS++.h> // Инициируем GPS TinyGPSPlus gps; #include <LiquidCrystal_1602_RUS.h> // Инициируем монитор LiquidCrystal_1602_RUS lcd(7, 5, 6, 8, 9, 10); //Порты для дисплея #include <bigNumbers.h> // Инициируем библиотеку отоброжения больших цифер bigNumbers <LiquidCrystal> bigNumbersLcd(&lcd); #include <SoftwareSerial.h> SoftwareSerial ss(4, 3); // Порты GPS RX 4; TX 3 int knop = 13; // Пин подключения кнопки переключения экрана int hour; // Переменная час int minute; // Переменная минуты int day; // Переменная день int month; // Переменная месяц int GMT = 11; // часовой пояс по Гринвичу (установить какой надо) int altitude; // Переменная высота byte customChar[8] = { // Создаём элемент Двоеточие (одна точка) B00000, B00000, B00000, B00000, B01110, B01110, B01110, B00000 }; byte customChar1[8] = { // Создаём элемент Двоеточие (вторая точка) B00000, B01110, B01110, B01110, B00000, B00000, B00000, B00000 }; void setup() { lcd.createChar(11, customChar); // Создаём симвло Двоеточие верхняя точка lcd.createChar(12, customChar1); // Создаём симвло Двоеточие нижняя точка pinMode(knop, INPUT); // Настраиваем порт кнопки на вход Serial.begin(115200); // Запуск последовательного интерфейса lcd.begin(20,4); // Дисплей 20 символов 4 строки bigNumbersLcd.intNumbers(); // Подключаем отоброжение больших цифер ss.begin(9600); // Скорость соеденения с GPS Serial.print(F("Biblioteca TinyGPS++ v. ")); Serial.println(TinyGPSPlus::libraryVersion()); // Выводим версию библиотеки в последовательный порт. Serial.println(); } void loop() { while (ss.available() > 0) (gps.encode(ss.read())); // читаем данные с GPS if (gps.time.isUpdated()) // проверяем данные времени на изменение { hour = gps.time.hour() + GMT; // читаем в переменную данные о часе + поправка на пояс. minute = gps.time.minute(); // читаем в переменную данные о минутах day = gps.date.day(); // читаем в переменную данные о дне if (hour > 23) day = day +1; // поправки связанные с применением часового пояса if (hour > 23) hour = hour - 24; } if (gps.altitude.isUpdated()) // проверяем данные высоты на изменение { altitude = gps.altitude.meters(); // читаем в переменную данные о Высоте } if (gps.date.isValid()) // проверяем данные даты на изменение { month = gps.date.month(); // читаем данные месяц } if(digitalRead(knop) == HIGH) { // Кнопка не нажата // Выводим время и дату // Отоброжение на экране LCD значения час (большими цифрами) if (hour <= 9) { bigNumbersLcd.printNumber(0, 1); // устанавливаем 0 для корректности отоброжения bigNumbersLcd.printNumber(hour, 5); // Отоброжаем значение час от 0 до 9 } if (hour > 9 & hour <= 19) { bigNumbersLcd.printNumber(1, 1); bigNumbersLcd.printNumber((hour-10), 5); // Отоброжаем значение час от 10 до 19 } if (hour > 19 & hour <= 23) { bigNumbersLcd.printNumber(2, 1); bigNumbersLcd.printNumber((hour-20), 5); // Отоброжаем значение час от 20 до 23 } // Отоброжваем двоеточие lcd.setCursor(9,0); // Установка курсора в 9 позицию 1 строки lcd.write((uint8_t)11); // Отоброжаем верхнюю точку Двоеточия lcd.setCursor(9,1); lcd.write((uint8_t)12); // Отоброжаем нижнюю точку Двоеточия // Отоброжаем Минуты (большими цифрами) if (minute <= 9) { bigNumbersLcd.printNumber(0, 11); // устанавливаем 0 для корректности отоброжения bigNumbersLcd.printNumber(minute, 15); // Отоброжаем значение минут от 0 до 9 } if (minute > 9 & minute <= 19) { bigNumbersLcd.printNumber(1, 11); bigNumbersLcd.printNumber((minute-10), 15); // Отоброжаем значение минут от 10 до 19 } if (minute > 19 & minute <= 29) { bigNumbersLcd.printNumber(2, 11); bigNumbersLcd.printNumber((minute-20), 15); // Отоброжаем значение минут от 20 до 29 } if (minute > 29 & minute <= 39) { bigNumbersLcd.printNumber(3, 11); bigNumbersLcd.printNumber((minute-30), 15); // Отоброжаем значение минут от 30 до 39 } if (minute > 39 & minute <= 49) { bigNumbersLcd.printNumber(4, 11); bigNumbersLcd.printNumber((minute-40), 15); // Отоброжаем значение минут от 40 до 49 } if (minute > 49 & minute <= 59) { bigNumbersLcd.printNumber(5, 11); bigNumbersLcd.printNumber((minute-50), 15); // Отоброжаем значение минут от 50 до 59 } // Отображение на LCD даты, месяца и года lcd.setCursor(5,3); //Установка курсора в 5 позицию 2 строки if (day <= 9)lcd.print("0"); // устанавливаем 0 для корректности отоброжения lcd.print(day);lcd.print(F("/")); // Отоброжение на экране LCD данных день if (month <= 9)lcd.print("0"); // устанавливаем 0 для корректности отоброжения lcd.print(month);lcd.print(F("/")); // Отоброжение на экране LCD данных месяц lcd.print(gps.date.year()); // Отоброжение на экране LCD данных год }else{ // Когда кнопка нажата // Выводим высоту и координаты lcd.setCursor(0,0); //Установка курсора в начало 1 строки lcd.print("Altitude = "); lcd.print(altitude); lcd.print(" m "); lcd.setCursor(0,2); //Установка курсора в начало 3 строки lcd.print("LAT = "); lcd.print(gps.location.lat(), 6); // отоброжаем широту lcd.setCursor(0,3); //Установка курсора в начало 4 строки lcd.print("LNG = "); lcd.print(gps.location.lng(), 6); // отоброжаем долготу delay(5000); lcd.clear(); //Очистка памяти диспея } // Отоброжаем данные в монтторе порта Serial.print(F(" ")); Serial.println(F("================================")); Serial.print(F(" ")); Serial.print(hour); Serial.print(F(":")); Serial.print(minute); //mes Serial.println(F(" ")); Serial.print(day); Serial.print(F("/")); Serial.print(month); Serial.print(F("/")); Serial.println(gps.date.year()); Serial.print("Высота = "); Serial.print(altitude); Serial.println(" м "); Serial.print("Широта = "); Serial.println(gps.location.lat(), 6); Serial.print("Долгота = "); Serial.println(gps.location.lng(), 6); //delay(500); }
Архивы со скетчем, библиотеками, схемой и STL файлами для печати корпусов устройства можно - скачать с яндекса.
Напишите отзыв.
Схема работы в принципе проста. GPS модуль принимает с низкоорбитальных спутников (четырёх и более) данные из которых вычисляет свое местоположение. Также с этих данных берётся точное время, дата и другие параметры.
Ардуино считывает необходимые данные с GPS модуля и выводит на четырёхстрочный LCD экран. Для лучшего восприятия цифры отображающие время сделаны высотой в две строчки, для этого используется библиотека bigNumbers.h. Данная библиотека может выводить цифры от 0 до 9. Для работы с модулем GPS используется библиотека TinyGPS++.h. Библиотека SoftwareSerial.h также необходима для связи с модулем GPS.
Для LCD экрана используется библиотека LiquidCrystal_1602_RUS.h (с поддержкой русского языка – если кто захочет сделать русские надписи на экране вместо а’нглцких). Подключение модуля GPS осуществляется по четырём проводам (VCC, TX, RX, GND), провода 1PPS и EN не используются (хотя 1PPS можно использовать для синхронизации устройств – это так, небольшое отступление).
Кнопка используется для переключения экранов. При нажатии кнопки окно с часами сменяется окном от отображающем координаты и высоту.
Схема устройства изображена на следующем рисунке.
В ходе эксплуатации часов обнаружился недостаток, это яркое свечение в ночное время. Вернее свечение то оставалось тем же, но в темноте оно ощущалось как свечение прожектора J. Поэтому была произведена небольшая доработка.
В схему был добавлен датчик KY-018 (фоторезистор), Датчик выводится на освещённую часть корпуса, через просверленное в корпусе отверстие. Модернизированная схема приведена ниже.
В скетч было добавлено несколько строк.
В переменные добавлено:
int photoresistorPin = A1; // выбор //вх.пина для фоторезистора
int ledPin = 12; // выбор пина // для регулятора подсветки
int photoresistorValue = 0; // переменная для значения // принятого от датчика
В void setup() добавлена строка:
pinMode(ledPin, OUTPUT);
В void loop() добавлены строки:
pinMode(ledPin, OUTPUT);
В void loop() добавлены строки:
photoresistorValue = analogRead(photoresistorPin);
if (photoresistorValue >= 512) digitalWrite(ledPin, HIGH); // значение // надо подбирать в зависимости
// от освещения
else digitalWrite(ledPin, LOW);
С помощью переменных резисторов «Яркость дисплея день» и «Яркость дисплея ночь», устанавливаем необходимое свечение экрана - соответственно при освещённом датчике и затемнённом.
GPS модуль располагается в открытой для спутников зоне, например на подоконнике окна. Подключение GPS к ардуино можно осуществить с помощью витой пары.