|
本帖最后由 jjbboox 于 2020-6-1 12:03 编辑
功能:
开机先显示一段数码管自检小动画
然后自动连接无线网络(数码管显示[c---]),秒点闪烁
如果是首次连接或者15秒内无法连接到上次使用的网络则进入自动配网状态,数码管显示[s---],此时可以用手机微信的安信可小程序配网
配网成功后显示[done],连接成功后自动通过NTP服务器同步时间,同步成功后开始时间显示。
配网成功后可以记住ssid和密码,下次开机除非无法连接,否则无需重新配网。
NTP服务器和同步间隔时间可以自己设置,代码中为8小时,可按自己需求修改,除非使用局域网中NTP服务器,否则不建议将时间间隔设置得过小。
只要把钟放在家里能连接到无线网络的地方,插上USB线就可以用。常年分秒不差。(Esp8266系列仅支持2.4G网络,5G的WiFi网络是连不上的)
硬件:
Esp8266或者Esp8285(没用到什么特殊的端口,我用的是安信可的Esp-01M,主要是因为体积小,加上扩展板双列直插,方便上洞洞板罢了)
TM1650(数码管驱动芯片)
共阴4位时钟专用数码管(自带秒点)
引脚连接请参考/doc/Pin_Map.txt
USB口使用的是淘宝买的micro USB小板,然后用1117-3.3降压以后给电路供电。
使用TM1650驱动数码管,无需使用限流电阻,亮度可调,发色均匀。
开源代码:
https://github.com/jjbboox/NTPClock_Esp8285
如果你还在使用老掉牙的Arduino IDE,请将main.cpp改名为NTPClock_Esp8285.ino,并将其他的*.h文件和*.cpp保存到ino相同的目录中即可
需要添加的Arduino库:
NTPClient
TM1650
正面:
背面(跳线比较乱):
视频连接
ESP8285(Esp8266) NTP时钟
为了方便不愿意点外链的朋友,下面把所有的源码贴出
main.cpp(NTPClock_Esp8285.ino)
- #include <NTPClient.h>
- #include <ESP8266WiFi.h>
- #include <WiFiUdp.h>
- #include <Wire.h>
- #include <TM1650.h>
- #include "air_kiss_connect.h"
- WiFiUDP ntpUDP;
- #define NTP_SERVER_ADDR "ntp.sjtu.edu.cn" // NTP服务器地址,可自行修改
- #define NTP_UPDATE_SECS (8*60*60) // 8小时同步一次时间
- // NTP服务器地址和同步间隔时间
- NTPClient timeClient(ntpUDP, NTP_SERVER_ADDR, NTP_UPDATE_SECS);
- // 驱动数码管的TM1650的I2C总线端口
- #define TM1650_SDA 9
- #define TM1650_SCL 10
- // 数码管小数点和冒号的数组下标
- // 使用4位共阴带冒号的时钟数码管
- // 不同型号的数码管点位不同,控制方式也会有所不同
- #define TM1650_DOT_POS 0
- #define TM1650_SEMICOLON_POS 1
- // 数码管对象实例
- TM1650 NixieTube(4);
- // AirKissConnect的状态回调函数
- void def_tick_fun(String str) {
- static bool dot;
- if(str.equalsIgnoreCase("START")) {
- NixieTube.clear();
- NixieTube.displayString("c---");
- }
- else if(str.equalsIgnoreCase("SMART")) {
- NixieTube.clear();
- NixieTube.displayString("s---");
- }
- else if(str.equalsIgnoreCase("Success")) {
- NixieTube.clear();
- NixieTube.displayString("done");
- }
- else if(str.equalsIgnoreCase(".")) {
- dot = !dot;
- NixieTube.setDot(TM1650_SEMICOLON_POS, dot);
- }
- }
- void I2C_init(uint8_t sda_pin, uint8_t scl_pin) {
- // TM1650 I2C总线设置为上拉
- pinMode(sda_pin, INPUT_PULLUP);
- pinMode(scl_pin, INPUT_PULLUP);
-
- // 初始化并启动I2C总线
- Wire.begin(sda_pin, scl_pin);
- }
- // 数码管显示剩余时间
- void show_timer(NTPClient &ntp_time) {
- // 显示缓存
- char str[5];
- // 打印显示字符串
- sprintf(str, "%02d%02d", ntp_time.getHours(), ntp_time.getMinutes());
- // 根据秒数的奇偶来切换":"显示
-
- str[TM1650_SEMICOLON_POS] |= (ntp_time.getSeconds()%2)?0x80:0x00;
- // 显示
- NixieTube.displayString(str);
- }
- void show_start() {
- uint8_t v = 0x01;
- for(int d = 0; d < 4; d++) {
- v = 1;
- NixieTube.clear();
- for(int i = 0; i < 7; i++) {
- NixieTube.setPosition(d, v);
- v <<= 1;
- delay(50);
- }
- }
- }
- void setup(){
- Serial.begin(115200);
- Serial.println("Serial Init Ok!");
-
- // 初始化I2C总线
- I2C_init(TM1650_SDA, TM1650_SCL);
-
- Serial.println("I2C init ok.");
- // 初始化数码管
- NixieTube.init();
- Serial.println("NixieTube init ok.");
- // 设置数码管亮度
- NixieTube.setBrightness(3);
-
- show_start();
-
- Serial.println("Air kiss connect start.");
- // 调用AirKissConnect配置无线网络,回调函数用来处理返回内容
- air_kiss_connect(def_tick_fun);
- // Wait for connection
- if(WiFi.status() != WL_CONNECTED) {
- Serial.println("Can not connect to WIFI!");
- NixieTube.displayString("Err ");
- }
- else {
- Serial.println("");
- Serial.print("Connected to ");
- Serial.println(WiFi.SSID());
- Serial.print("IP address: ");
- Serial.println(WiFi.localIP());
- }
-
- // 启动NTP连接获取同步时间
- timeClient.begin();
- }
- void clock_loop() {
- static uint32_t time_out = 0; // 刷新时间控制
- uint32_t now_mill = millis(); // 当前的系统时间
-
- // 如果系统计时器溢出
- if(now_mill >= time_out) {
- // 设定下次刷新的时间点(1s以后再次刷新)
- time_out = now_mill + 1000;
- // 更新TNP时间
- timeClient.update();
- Serial.println(timeClient.getFormattedTime());
- // 显示时间
- show_timer(timeClient);
- }
- }
- void loop() {
- clock_loop();
- }
复制代码
air_kiss.cpp
- #include <Arduino.h>
- #ifdef ESP32
- #include <WiFi.h>
- #else
- #include <ESP8266WiFi.h>
- #endif
- #ifdef _USER_SSID_
- const String ssid = "my_ssid_xxxx";
- const String pwd = "my_wifi_password";
- #endif
- void air_kiss_connect(void (*tick_fun)(String))
- {
- int cnt = 0;
- WiFi.mode(WIFI_STA);
- #ifdef _USER_SSID_
- WiFi.begin(ssid, pwd);
- #else
- WiFi.begin();
- #endif
- tick_fun("START");
- while (WiFi.status() != WL_CONNECTED)
- {
- delay(500);
- tick_fun(".");
- if (cnt++ >= 30)
- {
- tick_fun("SMART");
- WiFi.beginSmartConfig();
- while (true)
- {
- delay(1000);
- if (WiFi.smartConfigDone())
- {
- tick_fun("Success");
- // Serial.println("SmartConfig Success");
- while (WiFi.status() != WL_CONNECTED);
- break;
- }
- }
- }
- }
- }
复制代码
air_kiss_connect.h
- #ifndef _AIR_KISS_CONNECT_H_
- #define _AIR_KISS_CONNECT_H_
- void air_kiss_connect(void (*tick_fun)(String));
- #endif
复制代码
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
打赏
-
查看全部打赏
|