MENU

【歪门邪道】用Arduino从卫星上获取时间

February 2, 2018 • 瞎折腾

诸位好久不见啊,这几天我绝对不是去摸鱼了 2333

虽然其他年级已经进入寒假,但是我们苦逼的高三现在仍然还在补课,课余之时折腾一下新入坑的 Arduino,现在将 Hello World 发上来。

我记得最早碰这些东西,是小学五年级入坑单片机,但是还记得杜洋那个面包板入门单片机,套件买的那个黑啊。。。后来呢,一下子跳到树莓派,感觉 GPIO 好像也是有那么一些别扭,毕竟我喜欢 Java,不太喜欢 Python 的写法。于是呢,最近在同学的摇唇鼓舌之下,我买了个 Mega2560,刚刚又在淘宝上入了两个 nano 和一个 2560,争取在快递停运前买好东西,不让自己春节无聊。

那么接下来言归正传。通常来说入门一个什么东西都要写一个 Hello World,但是我觉得这个太简单了,于是上来就准备做一个 GPS 授时的钟,为我将来打算要做的辉光钟做个铺垫。就 GPS 模块而言,我用的是国产中科微的 ATGM336H-5N 主控芯片,号称是能够支持 GPS、北斗和格洛纳斯,但是实际来看,GPS 的信号更强,北斗的卫星只连上过一颗,而老毛子的格洛纳斯?不存在的。不过谁家的星都无所谓,能够接收到信号获取到 UTC 时间就行了,我用的是外接的陶瓷天线,在室内效果不错,有时候人品好甚至还能连上 4 颗卫星进行定位,但是即便没有四颗卫星,在一定条件下也能获取到时间的。

TIM图片20180202194049.jpg

目前使用 LCD1602 作为显示,使用 I2C 连接的 LCD2004 已经在路上了,个人感觉 1602 这个屏幕很鸡肋啊,基本上显示不了什么东西,而相比之下 2004 就有很大的富裕了。不过对于显示时间的工作,足够了。

我是用的 GPS 模块使用串口发送 NMEA-0183 语句。用惯了 Java 的 Split 之后再使用 C 进行字符处理就令我很头疼了。但是好在是描述时间的 ZDA 语句的格式是固定的,因此将 String 转化为 char 数组之后直接选取第几位进行显示就好了。

TIM截图20180202194502.png

顺带一提,关于 IDE,我用不惯 Arduino 官方给的 IDE。平时写程序喜欢用 IDEA 家的,前些日子在 Clion 上尝试了一下。Windows 上完败。我用的 Cygwin,而 avr-gcc 的编译器不在 linux 环境中,因此 clion 在编译时将 Cygwin 中的虚拟地址丢给 avr 编译器,编译器丈二和尚摸不着头脑,就报错了。后来我转战 linux,发现写代码时要引用正确的头文件才能做到自动补全函数,而 arduino 的语法和标准 C 又有不一样,因此 Clion 会经常报错,然而编译还是正常的。这就很难受了。因此我想到了很久前用的 sublime Text3,我买了正版,装了插件,一气呵成,妙哉妙哉。

关于代码,原本打算放在 github 上的,但是考虑到只有一个文件,我就贴在下面吧。写的不好,大佬们别喷 qwq

  • #include <avr/wdt.h>
  • #include <LiquidCrystal.h>
  • #include <Adafruit_GPS.h>
  • #include <Arduino.h>
  • Adafruit_GPS GPS(&Serial3); //Create GPS object
  • LiquidCrystal lcd(12,11, 10, 9, 8, 7, 6, 5, 4, 3, 2);
  • boolean flag = false;
  • void setup() {
  • wdt_enable(WDTO_2S);
  • pinMode(13,OUTPUT);
  • lcd.begin(16,2);
  • GPS.begin(9600); //Turn GPS on at baud rate of 9600
  • lcd.begin(16,2); // columns, rows. use 16,2 for a 16x2 LCD, etc.
  • lcd.clear(); // start with a blank screen
  • lcd.setCursor(0,0); // set cursor to column 0, row 0 (the first row)
  • lcd.print("Waiting for the"); // change this text to whatever you like. keep it clean.
  • lcd.setCursor(0,1); // set cursor to column 0, row 1
  • lcd.print(" satellites!");
  • }
  • char NMEA2[30];//30 is enough for time
  • void loop() {
  • while(!GPS.newNMEAreceived()) { //Keep reading characters in this loop until a good NMEA sentence is received
  • GPS.read(); //read a character from the GPS
  • }
  • GPS.parse(GPS.lastNMEA()); //Once you get a good NMEA, parse it
  • String NMEA1 = GPS.lastNMEA(); //Once parsed, save NMEA sentence into NMEA1
  • NMEA1.trim();
  • if(!flag) //if interruput not acitive, then write new value.
  • NMEA1.toCharArray(NMEA2,30);
  • light();
  • delay(250);
  • }
  • void show(){
  • lcd.clear();
  • lcd.setCursor(0,0);
  • lcd.print(" ");
  • lcd.print(NMEA2[24]);//print year
  • lcd.print(NMEA2[25]);
  • lcd.print(NMEA2[26]);
  • lcd.print(NMEA2[27]);
  • lcd.print(".");
  • lcd.print(NMEA2[21]);//print month
  • lcd.print(NMEA2[22]);
  • lcd.print(".");
  • lcd.print(NMEA2[18]);//print day
  • lcd.print(NMEA2[19]);
  • lcd.setCursor(0,1);
  • lcd.print(" ");
  • lcd.print(NMEA2[7]);//print hour
  • lcd.print(NMEA2[8]);
  • lcd.print(":");
  • lcd.print(NMEA2[9]);//print minute
  • lcd.print(NMEA2[10]);
  • lcd.print(":");
  • lcd.print(NMEA2[11]);//print second
  • lcd.print(NMEA2[12]);
  • lcd.print(" UTC");
  • }
  • void light(){
  • wdt_reset();
  • flag = true;
  • digitalWrite(13, HIGH);
  • if(NMEA2[0] == '$' && NMEA2[3]=='Z' && NMEA2[4]=='D' && NMEA2[5] == 'A' ){//if ZDA sentence
  • if(NMEA2[7] == ','){ //this means gps haven't get the time
  • lcd.clear();
  • lcd.setCursor(0,0); // set cursor to column 0, row 0 (the first row)
  • lcd.print("Waiting for the"); // change this text to whatever you like. keep it clean.
  • lcd.setCursor(0,1); // set cursor to column 0, row 1
  • lcd.print(" satellite!"); //little change to show gps is working but not get time yet
  • flag = false;
  • return;
  • }
  • show();
  • }
  • digitalWrite(13, LOW);
  • flag = false;
  • }

嗯,那么就是这样了。


知识共享许可协议
【歪门邪道】用 Arduino 从卫星上获取时间天空 Blond 采用 知识共享 署名 - 非商业性使用 - 相同方式共享 4.0 国际 许可协议进行许可。
本许可协议授权之外的使用权限可以从 https://skyblond.info/about.html 处获得。

Last Modified: March 31, 2023
Archives QR Code
QR Code for this page
Tipping QR Code