数码之家

 找回密码
 立即注册
搜索
查看: 1959|回复: 14

ESP8266模拟GPS时间报文

[复制链接]
发表于 2022-6-29 17:37:31 | 显示全部楼层 |阅读模式
50家元
1、模块ESP8266 ESP-01
2、连接通过手机扫描二维码配置模块网络
3、模块连接网络后,从NTP服务器获取时间、日期信息
4、将获取的时间、日期信息转换为NEMA0183RMC(GPS)报文格式从串口输出
5、RMC报文只需ID、UTC时间、状态A、UTC日期字段
例:$GPRMC,121252.000,A,,,,,,,070322,,,6、串口波特率9600

发表于 2022-6-29 18:29:14 | 显示全部楼层
以前刚好搬过一个代码!拿去用吧
  1. #include <ESP8266WiFi.h>
  2. #include <WiFiUdp.h>


  3. //needed for library
  4. #include <ESP8266WebServer.h>
  5. #include <DNSServer.h>
  6. #include <WiFiManager.h>          //https://github.com/tzapu/WiFiManager

  7. // select which pin will trigger the configuration portal when set to LOW
  8. // ESP-01 users please note: the only pins available (0 and 2), are shared
  9. // with the bootloader, so always set them HIGH at power-up
  10. #define TRIGGER_PIN 0




  11. //NTP
  12. #define time_zone  0  //时区(要格林尼治时间加减的小时,北京为东八区,要将格林威治时间+8小时)
  13. unsigned int localPort = 2390;      // local port to listen for UDP packets
  14. /* Don't hardwire the IP address or we won't get the benefits of the pool.
  15.     Lookup the IP address for the host name instead */
  16. //IPAddress timeServer(129, 6, 15, 28); // time.nist.gov NTP server
  17. IPAddress timeServerIP; // time.nist.gov NTP server address
  18. const char* ntpServerName = "ntp1.aliyun.com";
  19. const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
  20. byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
  21. // A UDP instance to let us send and receive packets over UDP
  22. WiFiUDP udp;


  23. void setup()
  24. {


  25.   pinMode(TRIGGER_PIN, INPUT);
  26.   //初始化
  27.   Serial.begin(9600);//串口波特率115200
  28.     delay(1000);
  29. delay(5000);
  30.    pinMode(LED_BUILTIN, OUTPUT);
  31.      Serial.println("\n Starting");
  32. digitalWrite(LED_BUILTIN, HIGH);
  33. // is configuration portal requested?
  34.   if ( digitalRead(TRIGGER_PIN) == LOW ) {
  35.         // turn the LED on (HIGH is the voltage level)
  36.     //WiFiManager
  37.     //Local intialization. Once its business is done, there is no need to keep it around
  38.     WiFiManager wifiManager;

  39.     digitalWrite(LED_BUILTIN, LOW);

  40.     //reset settings - for testing
  41.     //wifiManager.resetSettings();

  42.     //sets timeout until configuration portal gets turned off
  43.     //useful to make it all retry or go to sleep
  44.     //in seconds
  45.     //wifiManager.setTimeout(120);

  46.     //it starts an access point with the specified name
  47.     //here  "AutoConnectAP"
  48.     //and goes into a blocking loop awaiting configuration

  49.     //WITHOUT THIS THE AP DOES NOT SEEM TO WORK PROPERLY WITH SDK 1.5 , update to at least 1.5.1
  50.     //WiFi.mode(WIFI_STA);
  51.    
  52.     if (!wifiManager.startConfigPortal("LED-Clock")) {
  53.       Serial.println("failed to connect and hit timeout");
  54.       delay(3000);
  55.       //reset and try again, or maybe put it to deep sleep
  56.       ESP.reset();
  57.       delay(5000);
  58.     }

  59.     //if you get here you have connected to the WiFi
  60.     Serial.println("connected...yeey :)");
  61.   }
  62. digitalWrite(LED_BUILTIN, HIGH);    // turn the LED off by making the voltage LOW
  63.   delay(1000);   


  64.   udp.begin(localPort);
  65.   Serial.print("Local port: ");
  66.   Serial.println(udp.localPort());


  67. }
  68. void loop()
  69. {
  70.   if (WiFi.status() != WL_CONNECTED)
  71.   {
  72.     Serial.println(".");
  73.       delay(1000);
  74.   }
  75.   else
  76.   {
  77.     //get a random server from the pool
  78.     WiFi.hostByName(ntpServerName, timeServerIP);

  79.     sendNTPpacket(timeServerIP); // send an NTP packet to a time server
  80.     // wait to see if a reply is available
  81.     delay(5000);

  82.     int cb = udp.parsePacket();
  83.     if (!cb) {
  84.       //   Serial.println("no packet yet");
  85.       Serial.println("$GPRMC,000000.KLE,V,,,,,,,08092019,,,,");
  86. Serial.println("$BDRMC,000000.KLE,V,,,,,,,08092019,,,,");
  87.       return;
  88.     }
  89.     else {

  90.       //NTP
  91.       //    Serial.print("packet received, length=");
  92.       //    Serial.println(cb);
  93.       // We've received a packet, read the data from it
  94.       udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
  95.       //the timestamp starts at byte 40 of the received packet and is four bytes,
  96.       // or two words, long. First, esxtract the two words:
  97.       unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
  98.       unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
  99.       // combine the four bytes (two words) into a long integer
  100.       // this is NTP time (seconds since Jan 1 1900):
  101.       unsigned long secsSince1900 = highWord << 16 | lowWord;
  102.       //  Serial.print("Seconds since Jan 1 1900 = " );
  103.       //   Serial.println(secsSince1900);
  104.       // now convert NTP time into everyday time:
  105.       //   Serial.print("Unix time = ");
  106.       // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
  107.       const unsigned long seventyYears = 2208988800UL;
  108.       // subtract seventy years:
  109.       unsigned long epoch = secsSince1900 - seventyYears;
  110.       // print Unix time:
  111.       //   Serial.println(epoch);

  112.       unsigned long Time = time_zone * 3600 + epoch;
  113.       unsigned long Y2KTime = (Time - 946684800) / 86400;//从2000年开始的天数
  114.       unsigned long YTime;//从今年开始的天数
  115.       unsigned int Year;
  116.       unsigned int Month = 0;
  117.       unsigned long Day;

  118.       unsigned int shi;
  119.       unsigned int  fen;
  120.       unsigned int  miao;

  121.       //日期
  122.       if (Y2KTime % 146097 <= 36525)
  123.       {
  124.         Year = 2000 + Y2KTime / 146097 * 400 + Y2KTime % 146097 / 1461 * 4 + (Y2KTime % 146097 % 1461 - 1) / 365;
  125.         YTime = (Y2KTime % 146097 % 1461 - 1) % 365 + 1;
  126.       }
  127.       else
  128.       {
  129.         Year = 2000 + Y2KTime / 146097 * 400 + (Y2KTime % 146097 - 1) / 36524 * 100 + ((Y2KTime % 146097 - 1) % 36524 + 1) / 1461 * 4 + (((Y2KTime % 146097 - 1) % 36524 + 1) % 1461 - 1) / 365;
  130.         YTime = (((Y2KTime % 146097 - 1) % 36524 + 1) % 1461 - 1) % 365 + 1;
  131.       }
  132.       Day = YTime;
  133.       unsigned char f = 1; //循环标志
  134.       while (f)
  135.       {
  136.         switch (Month)
  137.         {
  138.           case 0:
  139.             if (Day < 31)
  140.               f = 0;
  141.             else
  142.               Day -= 31;
  143.             break;
  144.           case 1:
  145.             if (Day < 29)
  146.               f = 0;
  147.             else
  148.             {
  149.               if (LY(Year))
  150.               {
  151.                 Day -= 29;
  152.               }
  153.               else
  154.               {
  155.                 Day -= 28;
  156.               }
  157.             }
  158.             break;
  159.           case 2:
  160.             if (Day < 31)
  161.               f = 0;
  162.             else
  163.               Day -= 31;
  164.             break;
  165.           case 3:
  166.             if (Day < 30)
  167.               f = 0;
  168.             else
  169.               Day -= 30;
  170.             break;
  171.           case 4:
  172.             if (Day < 31)
  173.               f = 0;
  174.             else
  175.               Day -= 31;
  176.             break;
  177.           case 5:
  178.             if (Day < 30)
  179.               f = 0;
  180.             else
  181.               Day -= 30;
  182.             break;
  183.           case 6:
  184.             if (Day < 31)
  185.               f = 0;
  186.             else
  187.               Day -= 31;
  188.             break;
  189.           case 7:
  190.             if (Day < 31)
  191.               f = 0;
  192.             else
  193.               Day -= 31;
  194.             break;
  195.           case 8:
  196.             if (Day < 30)
  197.               f = 0;
  198.             else
  199.               Day -= 30;
  200.             break;
  201.           case 9:
  202.             if (Day < 31)
  203.               f = 0;
  204.             else
  205.               Day -= 31;
  206.             break;
  207.           case 10:
  208.             if (Day < 30)
  209.               f = 0;
  210.             else
  211.               Day -= 30;
  212.             break;
  213.           case 11:
  214.             if (Day < 31)
  215.               f = 0;
  216.             else
  217.               Day -= 31;
  218.             break;
  219.         }
  220.         Month += 1;
  221.       }
  222.       Day += 1;


  223.       /***星期
  224.         switch (Y2KTime % 7) //2000年1月1日是星期六
  225.         {
  226.         case 0: display.drawBitmap(112, 48, weekData6, 16, 16, WHITE); break;
  227.         case 1: display.drawBitmap(112, 48, weekData7, 16, 16, WHITE); break;
  228.         case 2: display.drawBitmap(112, 48, weekData1, 16, 16, WHITE); break;
  229.         case 3: display.drawBitmap(112, 48, weekData2, 16, 16, WHITE); break;
  230.         case 4: display.drawBitmap(112, 48, weekData3, 16, 16, WHITE); break;
  231.         case 5: display.drawBitmap(112, 48, weekData4, 16, 16, WHITE); break;
  232.         case 6: display.drawBitmap(112, 48, weekData5, 16, 16, WHITE); break;
  233.         }
  234.       ***/

  235.       //时间

  236.       // print the hour, minute and second:
  237.       if ((Time  % 86400L) / 3600 < 10)
  238.       {
  239.         shi = 0;
  240.         //  Serial.print('00');
  241.       }
  242.       //      Serial.print("The time is ");       // UTC is the time at Greenwich Meridian (GMT)
  243.       // Serial.print((Time  % 86400L) / 3600); // print the hour (86400 equals secs per day)
  244.       shi = ((Time  % 86400L) / 3600);
  245.       //     Serial.print(':');

  246.       if ( ((Time % 3600) / 60) < 10 ) {
  247.         // In the first 10 minutes of each hour, we'll want a leading '0'
  248.         // Serial.print('0');
  249.         fen = 0;
  250.       }
  251.       fen = fen + ((Time  % 3600) / 60);

  252.       //   Serial.print((Time  % 3600) / 60); // print the minute (3600 equals secs per minute)

  253.       //   Serial.print(':');
  254.       if ( (Time % 60) < 10 ) {
  255.         // In the first 10 seconds of each minute, we'll want a leading '0'
  256.         //  Serial.print('0');
  257.         miao = 0;
  258.       }
  259.       miao = miao + (Time % 60);
  260.       //   Serial.print(Time % 60); // print the second


  261.       //China time:23/3/2018 - 17:15:48 - Friday
  262.       //$GPRMC,091548.lbq,A,,,,,,,230318,,,,

  263.       Serial.print("$GPRMC,");
  264.       
  265. if (shi<10){Serial.print('0');}
  266. Serial.print(shi);
  267. if (fen<10){Serial.print('0');}
  268. Serial.print(fen);
  269. if (miao<10){Serial.print('0');}
  270. Serial.print(miao);

  271.       Serial.print(".KLE,A,,,,,,,");

  272.       if ( (Day) < 10 ) {Serial.print('0');}
  273.       Serial.print(Day);
  274.       if ( (Month) < 10 ) {Serial.print('0');}
  275.       Serial.print(Month);
  276.       Serial.print(Year);
  277.       Serial.println(",,,,");
  278.       
  279.       //$BDRMC,091548.lbq,A,,,,,,,230318,,,,

  280.       Serial.print("$BDRMC,");
  281.       
  282. if (shi<10){Serial.print('0');}
  283. Serial.print(shi);
  284. if (fen<10){Serial.print('0');}
  285. Serial.print(fen);
  286. if (miao<10){Serial.print('0');}
  287. Serial.print(miao);

  288.       Serial.print(".KLE,A,,,,,,,");

  289.       if ( (Day) < 10 ) {Serial.print('0');}
  290.       Serial.print(Day);
  291.       if ( (Month) < 10 ) {Serial.print('0');}
  292.       Serial.print(Month);
  293.       Serial.print(Year);
  294.       Serial.println(",,,,");







  295.     }
  296.     //   display.update();
  297.   }
  298. }

  299. // send an NTP request to the time server at the given address
  300. unsigned long sendNTPpacket(IPAddress& address)
  301. {
  302.   // Serial.println("sending NTP packet...");
  303.   // set all bytes in the buffer to 0
  304.   memset(packetBuffer, 0, NTP_PACKET_SIZE);
  305.   // Initialize values needed to form NTP request
  306.   // (see URL above for details on the packets)
  307.   packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  308.   packetBuffer[1] = 0;     // Stratum, or type of clock
  309.   packetBuffer[2] = 6;     // Polling Interval
  310.   packetBuffer[3] = 0xEC;  // Peer Clock Precision
  311.   // 8 bytes of zero for Root Delay & Root Dispersion
  312.   packetBuffer[12]  = 49;
  313.   packetBuffer[13]  = 0x4E;
  314.   packetBuffer[14]  = 49;
  315.   packetBuffer[15]  = 52;

  316.   // all NTP fields have been given values, now
  317.   // you can send a packet requesting a timestamp:
  318.   udp.beginPacket(address, 123); //NTP requests are to port 123
  319.   udp.write(packetBuffer, NTP_PACKET_SIZE);
  320.   udp.endPacket();
  321. }
  322. unsigned char LY(unsigned int y)//判断是否为闰年
  323. {
  324.   if (y % 400 == 0)
  325.     return 1;
  326.   if (y % 100 == 0)
  327.     return 0;
  328.   if (y % 4 == 0)
  329.     return 1;
  330. }
复制代码
回复

使用道具 举报

 楼主| 发表于 2022-6-29 18:44:59 | 显示全部楼层
72hour 发表于 2022-6-29 18:29
以前刚好搬过一个代码!拿去用吧

@72hour 非常感谢您!我先测试一下。
回复

使用道具 举报

发表于 2022-7-2 17:41:53 | 显示全部楼层
论坛里面牛人就是多
回复

使用道具 举报

发表于 2022-7-5 02:15:57 | 显示全部楼层
来学习了~
回复

使用道具 举报

发表于 2022-7-8 00:14:32 | 显示全部楼层
怎么感觉要做坏事呢
回复

使用道具 举报

发表于 2022-7-8 12:37:15 | 显示全部楼层
知道星链系统为什么可以干扰定位系统了吧。实际上,昨天俄罗斯的7枚导弹发射后螺旋坠落地面,估计是跟星链有关。希望北斗的搞干扰能强点。
回复

使用道具 举报

发表于 2022-7-11 19:04:18 | 显示全部楼层
码住了,很厉害啊。
回复

使用道具 举报

发表于 2022-7-14 17:50:18 | 显示全部楼层
72hour 发表于 2022-6-29 18:29
以前刚好搬过一个代码!拿去用吧

再加一个配置NTP服务器的网页页面啊
回复

使用道具 举报

发表于 2022-7-25 00:01:52 来自手机浏览器 | 显示全部楼层
gps模块直接用不方便吗,丢窗口就行了
回复

使用道具 举报

发表于 2022-8-8 07:59:57 | 显示全部楼层
论坛里面牛人就是多
回复

使用道具 举报

发表于 2023-8-6 08:23:55 | 显示全部楼层
论坛里面牛人多
回复

使用道具 举报

发表于 2023-8-7 08:46:27 | 显示全部楼层
一个代码
回复

使用道具 举报

发表于 2023-8-7 12:00:55 来自手机浏览器 | 显示全部楼层
高手在民间
回复

使用道具 举报

发表于 2024-3-17 18:32:07 | 显示全部楼层
过来学习了,感谢各位大佬的分享!!!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2024-4-25 21:44 , Processed in 0.202800 second(s), 9 queries , Redis On.

Powered by Discuz!

© 2006-2023 smzj.net

快速回复 返回顶部 返回列表