数码之家

 找回密码
 立即注册
搜索
查看: 23006|回复: 81

[Arduino] DIY ESP8266 WIFI自动校时LED点阵滚动时钟,支持OTA升级/自动调节亮度

    [复制链接]
发表于 2019-12-25 17:51:27 | 显示全部楼层 |阅读模式

爱科技、爱创意、爱折腾、爱极致,我们都是技术控

您需要 登录 才可以下载或查看,没有账号?立即注册

x
今天再给大家分享一个连接WIFI自动校时的LED点阵滚动时钟,参考外网程序加自己修改,主要特点:
1.无需RTC芯片,WIFI连接外网NTP服务器,定期更新时间,只要有网络,永远不用调整时间。
2.使用WIFI管理器热点配置WIF密码;
3.秒部分向下滚动显示,在分钟的固定时间横向滚动显示日期及星期;
4.带有LDR光敏电阻检测环境亮度自动调整显示屏的亮度;
5.增加OTA升级,调试更新固件无需连接USB线;
6.增加WIFI连接指示灯,提示联网状态。

之前分享的两个基于ESP8266的小制作:
ESP8266 安卓APP自定义控制WS2812B彩灯串
ESP8266 驱动圆形60串WS2812全彩LED制作的模拟走时动画时钟
软件配置,库安装,WIFI管理器设置等请参考第一帖,本帖不在赘述。

照例,先放效果图:
HE.jpg
WIF.jpg
TIM.jpg
2019.jpg

硬件接线图:
QQ截图20191225172039.jpg


除了NodeMCU开发板外,使用的主要部件有两个:
1. LDR光敏电阻,用于检测环境光线,如果有旧的声控灯头,直接拆里面的使用。
QQ截图20191225172527.jpg

2.MAX7219驱动的8*8矩阵点阵,该IC使用串行口驱动,芯片可级联多级驱动,一般有单位,或者4位、6位等,我们需要使用6位(可以使用一个4位再加一个2位),即组成48*8点阵。
7219sch.jpg




u=1581876771,496398749&fm=26&gp=0.jpg
DD.jpg

点阵显示PCB为自己Layout,捷配或嘉立创打样
QQ截图20191226094224.png


PCB附件下载:
MAX7219-8X16 V0.zip (91.53 KB, 下载次数: 96)

8*8点阵资料,使用共阴点阵
88.jpg


软件代码:
  1. //MatrixClock
  2. //OTA,WiFiManager
  3. //without RTC
  4. //LDR-A0,自动亮度
  5. //开机LOGO

  6. /*
  7.   ===================
  8.   MAX7219 to ESP8266
  9.   ===================
  10.   VCC - 5V
  11.   GND - GND
  12.   CS  - D8
  13.   DIN - D7
  14.   CLK - D5
  15.   ===========================================
  16.   LDR light sensor module to ESP8266
  17.   ============================================
  18.   VCC - 3.3V
  19.   GND - GND
  20.   OUT - A0
  21.   ========================================================
  22.   WiFi led to ESP8266
  23.   ========================================================
  24.   D3--|<|---[1K]--3.3v

  25. */

  26. #include <SPI.h>
  27. #include <Ticker.h>
  28. #include <ArduinoOTA.h>
  29. #include <DNSServer.h>
  30. #include <ESP8266WiFi.h>
  31. #include <ESP8266WebServer.h>
  32. #include <WiFiManager.h>
  33. #include <WifiUDP.h>
  34. #include <Wire.h>
  35. #include <NTPClient.h>   //更新get year, month, day

  36. //Beijin time define
  37. #define NTP_OFFSET     8*3600                    //+8h,北京时间
  38. #define NTP_INTERVAL   12*60*60*1000             //12*60*60*1000  12 hours 更新
  39. #define NTP_ADDRESS  "ntp1.aliyun.com"
  40. //#define NTP_ADDRESS    "time1.cloud.tencent.com"

  41. /*************************************************************************************************
  42.   time.pool.aliyun.com
  43.   time1.aliyun.com
  44.   time2.aliyun.com
  45.   time3.aliyun.com
  46.   time4.aliyun.com
  47.   time5.aliyun.com
  48.   time6.aliyun.com
  49.   time7.aliyun.com

  50.   time1.cloud.tencent.com
  51.   time2.cloud.tencent.com
  52.   time3.cloud.tencent.com
  53.   time4.cloud.tencent.com
  54.   time5.cloud.tencent.com
  55. *************************************************************************************************/

  56. #define wf_led  2      // 0,D3
  57. #define CS             15     // D8=cs Pin(SPI) D5=CLK, D7=DI
  58. #define anzMAX         6      // number of led matrix Modules
  59. unsigned short maxPosX = anzMAX * 8 - 1;                         //计算最大位置
  60. unsigned short LEDarr[anzMAX][8];                                        //要显示的字符矩阵(40 * 8)
  61. unsigned short helpArrMAX[anzMAX * 8];                            //字符的辅助数组
  62. unsigned short helpArrPos[anzMAX * 8];                                //字符的辅助数组pos
  63. unsigned int z_PosX = 0;                                                        //xPosition 用于时间显示
  64. unsigned int d_PosX = 0;                            //xPosition 用于日期显示
  65. bool f_tckr1s = false;
  66. bool f_tckr1h = false;
  67. bool f_tckr50ms = false;
  68. bool f_tckr24h = false;


  69. #define DATATIME_PRINT
  70. #define CHINESE_CALENDAR                            //中国日历显示方式 1900-01-01,星期
  71. #define LDR_SENSOR
  72. #define LDR_DEBUG

  73. #ifdef LDR_SENSOR
  74. int A0LDR = A0;        // A0 analoog LDR in
  75. #endif

  76. // The object for the Ticker
  77. Ticker tckr;

  78. // Set up the NTP UDP client
  79. WiFiUDP ntpUDP;
  80. NTPClient timeClient(ntpUDP, NTP_ADDRESS, NTP_OFFSET, NTP_INTERVAL);

  81. // other displays -------------------------------------
  82. //#define REVERSE_HORIZONTAL                           // Parola, Generic and IC-Station 反转水平
  83. //#define REVERSE_VERTICAL                             // IC-Station display 反转垂直
  84. //#define ROTATE_90                                    // Generic display    旋转90度
  85. /*
  86.    p  A  B  C  D  E  F  G        7  6  5  4  3  2  1  0        G  F  E  D  C  B  A  p        G  F  E  D  C  B  A  p
  87.   ------------------------      ------------------------      ------------------------      ------------------------
  88.   0 |o  o  o  o  o  o  o  o|    p |o  o  o  o  o  o  o  o|    0 |o  o  o  o  o  o  o  o|    7 |o  o  o  o  o  o  o  o|
  89.   1 |o  o  o  o  o  o  o  o|    A |o  o  o  o  o  o  o  o|    1 |o  o  o  o  o  o  o  o|    6 |o  o  o  o  o  o  o  o|
  90.   2 |o  o  o  o  o  o  o  o|    B |o  o  o  o  o  o  o  o|    2 |o  o  o  o  o  o  o  o|    5 |o  o  o  o  o  o  o  o|
  91.   3 |o  o              o  o|    C |o  o              o  o|    3 |o  o              o  o|    4 |o  o              o  o|
  92.   4 |o  o    FC-16     o  o|    D |o  o   Generic    o  o|    4 |o  o   Parola     o  o|    3 |o  o  IC-Station  o  o|
  93.   5 |o  o              o  o|    E |o  o              o  o|    5 |o  o              o  o|    2 |o  o              o  o|
  94.   6 |o  o  o  o  o  o  o  o|    F |o  o  o  o  o  o  o  o|    6 |o  o  o  o  o  o  o  o|    1 |o  o  o  o  o  o  o  o|
  95.   7 |o  o  o  o  o  o  o  o|    G |o  o  o  o  o  o  o  o|    7 |o  o  o  o  o  o  o  o|    0 |o  o  o  o  o  o  o  o|
  96.   ------------------------      ------------------------      ------------------------      ------------------------
  97. */
  98. #ifdef CHINESE_CALENDAR
  99. //months
  100. char M_arr[12][4] = {
  101.   { '.', '0', '1', '.' },
  102.   { '.', '0', '2', '.' },
  103.   { '.', '0', '3', '.' },
  104.   { '.', '0', '4', '.' },
  105.   { '.', '0', '5', '.' },
  106.   { '.', '0', '6', '.' },
  107.   { '.', '0', '7', '.' },
  108.   { '.', '0', '8', '.' },
  109.   { '.', '0', '9', '.' },
  110.   { '.', '1', '0', '.' },
  111.   { '.', '1', '1', '.' },
  112.   { '.', '1', '2', '.' }
  113. };
  114. //days
  115. char WT_arr[7][3] = {
  116.   { 'S', 'u', 'n'},
  117.   { 'M', 'o', 'n'},
  118.   { 'T', 'u', 'e'},
  119.   { 'W', 'e', 'd'},
  120.   { 'T', 'h', 'u'},
  121.   { 'F', 'r', 'i'},
  122.   { 'S', 'a', 't'}
  123. };
  124. #else
  125. //months
  126. char M_arr[12][5] = { { '.', 'J', 'a', 'n', '.' }, { '.', 'F', 'e', 'b', '.' },
  127.   { '.', 'M', 'a', 'r', '.' }, { '.', 'A', 'p', 'r', '.' }, { '.', 'M', 'a', 'y', ' ' }, { '.', 'J', 'u', 'n', 'e' }, { '.', 'J', 'u', 'l', 'y' },
  128.   { '.', 'A', 'u', 'g', '.' }, { '.', 'S', 'e', 'p', 't' }, { '.', 'O', 'c', 't', '.' }, { '.', 'N', 'o', 'v', '.' }, { '.', 'D', 'e', 'c', '.' }
  129. };
  130. //days
  131. char WT_arr[7][4] = { { 'S', 'u', 'n', ',' }, { 'M', 'o', 'n', ',' }, { 'T', 'u', 'e', ',' }, { 'W', 'e', 'd', ',' }, { 'T', 'h', 'u', ',' },
  132.   { 'F', 'r', 'i', ',' }, { 'S', 'a', 't', ',' }
  133. };
  134. #endif


  135. // 8x8矩阵中的字符集5x8,0,0在右上角
  136. unsigned short const font1[96][9] = { {
  137.     0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // 0x20, Space
  138.   { 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x04, 0x00 },   // 0x21, !
  139.   { 0x07, 0x09, 0x09, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00 },   // 0x22, "
  140.   { 0x07, 0x0a, 0x0a, 0x1f, 0x0a, 0x1f, 0x0a, 0x0a, 0x00 },   // 0x23, #
  141.   { 0x07, 0x04, 0x0f, 0x14, 0x0e, 0x05, 0x1e, 0x04, 0x00 },   // 0x24, $
  142.   { 0x07, 0x19, 0x19, 0x02, 0x04, 0x08, 0x13, 0x13, 0x00 },   // 0x25, %
  143.   { 0x07, 0x04, 0x0a, 0x0a, 0x0a, 0x15, 0x12, 0x0d, 0x00 },   // 0x26, &
  144.   { 0x07, 0x04, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 },   // 0x27, '
  145.   { 0x07, 0x02, 0x04, 0x08, 0x08, 0x08, 0x04, 0x02, 0x00 },   // 0x28, (
  146.   { 0x07, 0x08, 0x04, 0x02, 0x02, 0x02, 0x04, 0x08, 0x00 },   // 0x29, )
  147.   { 0x07, 0x04, 0x15, 0x0e, 0x1f, 0x0e, 0x15, 0x04, 0x00 },   // 0x2a, *
  148.   { 0x07, 0x00, 0x04, 0x04, 0x1f, 0x04, 0x04, 0x00, 0x00 },   // 0x2b, +
  149.   { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02 },   // 0x2c, ,
  150.   { 0x07, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00 },   // 0x2d, -
  151.   { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00 },   // 0x2e, .
  152.   { 0x07, 0x01, 0x01, 0x02, 0x04, 0x08, 0x10, 0x10, 0x00 },   // 0x2f, /
  153.   { 0x07, 0x0e, 0x11, 0x13, 0x15, 0x19, 0x11, 0x0e, 0x00 },   // 0x30, 0
  154.   { 0x07, 0x04, 0x0c, 0x04, 0x04, 0x04, 0x04, 0x0e, 0x00 },   // 0x31, 1
  155.   { 0x07, 0x0e, 0x11, 0x01, 0x02, 0x04, 0x08, 0x1f, 0x00 },   // 0x32, 2
  156.   { 0x07, 0x0e, 0x11, 0x01, 0x06, 0x01, 0x11, 0x0e, 0x00 },   // 0x33, 3
  157.   { 0x07, 0x02, 0x06, 0x0a, 0x12, 0x1f, 0x02, 0x02, 0x00 },   // 0x34, 4
  158.   { 0x07, 0x1f, 0x10, 0x1e, 0x01, 0x01, 0x11, 0x0e, 0x00 },   // 0x35, 5
  159.   { 0x07, 0x06, 0x08, 0x10, 0x1e, 0x11, 0x11, 0x0e, 0x00 },   // 0x36, 6
  160.   { 0x07, 0x1f, 0x01, 0x02, 0x04, 0x08, 0x08, 0x08, 0x00 },   // 0x37, 7
  161.   { 0x07, 0x0e, 0x11, 0x11, 0x0e, 0x11, 0x11, 0x0e, 0x00 },   // 0x38, 8
  162.   { 0x07, 0x0e, 0x11, 0x11, 0x0f, 0x01, 0x02, 0x0c, 0x00 },   // 0x39, 9
  163.   { 0x04, 0x00, 0x03, 0x03, 0x00, 0x03, 0x03, 0x00, 0x00 },   // 0x3a, :
  164.   { 0x07, 0x00, 0x0c, 0x0c, 0x00, 0x0c, 0x04, 0x08, 0x00 },   // 0x3b, ;
  165.   { 0x07, 0x02, 0x04, 0x08, 0x10, 0x08, 0x04, 0x02, 0x00 },   // 0x3c, <
  166.   { 0x07, 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00 },   // 0x3d, =
  167.   { 0x07, 0x08, 0x04, 0x02, 0x01, 0x02, 0x04, 0x08, 0x00 },   // 0x3e, >
  168.   { 0x07, 0x0e, 0x11, 0x01, 0x02, 0x04, 0x00, 0x04, 0x00 },   // 0x3f, ?
  169.   { 0x07, 0x0e, 0x11, 0x17, 0x15, 0x17, 0x10, 0x0f, 0x00 },   // 0x40, @
  170.   { 0x07, 0x04, 0x0a, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x00 },   // 0x41, A
  171.   { 0x07, 0x1e, 0x11, 0x11, 0x1e, 0x11, 0x11, 0x1e, 0x00 },   // 0x42, B
  172.   { 0x07, 0x0e, 0x11, 0x10, 0x10, 0x10, 0x11, 0x0e, 0x00 },   // 0x43, C
  173.   { 0x07, 0x1e, 0x09, 0x09, 0x09, 0x09, 0x09, 0x1e, 0x00 },   // 0x44, D
  174.   { 0x07, 0x1f, 0x10, 0x10, 0x1c, 0x10, 0x10, 0x1f, 0x00 },   // 0x45, E
  175.   { 0x07, 0x1f, 0x10, 0x10, 0x1f, 0x10, 0x10, 0x10, 0x00 },   // 0x46, F
  176.   { 0x07, 0x0e, 0x11, 0x10, 0x10, 0x13, 0x11, 0x0f, 0x00 },   // 0x37, G
  177.   { 0x07, 0x11, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11, 0x00 },   // 0x48, H
  178.   { 0x07, 0x0e, 0x04, 0x04, 0x04, 0x04, 0x04, 0x0e, 0x00 },   // 0x49, I
  179.   { 0x07, 0x1f, 0x02, 0x02, 0x02, 0x02, 0x12, 0x0c, 0x00 },   // 0x4a, J
  180.   { 0x07, 0x11, 0x12, 0x14, 0x18, 0x14, 0x12, 0x11, 0x00 },   // 0x4b, K
  181.   { 0x07, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1f, 0x00 },   // 0x4c, L
  182.   { 0x07, 0x11, 0x1b, 0x15, 0x11, 0x11, 0x11, 0x11, 0x00 },   // 0x4d, M
  183.   { 0x07, 0x11, 0x11, 0x19, 0x15, 0x13, 0x11, 0x11, 0x00 },   // 0x4e, N
  184.   { 0x07, 0x0e, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e, 0x00 },   // 0x4f, O
  185.   { 0x07, 0x1e, 0x11, 0x11, 0x1e, 0x10, 0x10, 0x10, 0x00 },   // 0x50, P
  186.   { 0x07, 0x0e, 0x11, 0x11, 0x11, 0x15, 0x12, 0x0d, 0x00 },   // 0x51, Q
  187.   { 0x07, 0x1e, 0x11, 0x11, 0x1e, 0x14, 0x12, 0x11, 0x00 },   // 0x52, R
  188.   { 0x07, 0x0e, 0x11, 0x10, 0x0e, 0x01, 0x11, 0x0e, 0x00 },   // 0x53, S
  189.   { 0x07, 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00 },   // 0x54, T
  190.   { 0x07, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e, 0x00 },   // 0x55, U
  191.   { 0x07, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0a, 0x04, 0x00 },   // 0x56, V
  192.   { 0x07, 0x11, 0x11, 0x11, 0x15, 0x15, 0x1b, 0x11, 0x00 },   // 0x57, W
  193.   { 0x07, 0x11, 0x11, 0x0a, 0x04, 0x0a, 0x11, 0x11, 0x00 },   // 0x58, X
  194.   { 0x07, 0x11, 0x11, 0x0a, 0x04, 0x04, 0x04, 0x04, 0x00 },   // 0x59, Y
  195.   { 0x07, 0x1f, 0x01, 0x02, 0x04, 0x08, 0x10, 0x1f, 0x00 },   // 0x5a, Z
  196.   { 0x07, 0x0e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0e, 0x00 },   // 0x5b, [
  197.   { 0x07, 0x10, 0x10, 0x08, 0x04, 0x02, 0x01, 0x01, 0x00 },   // 0x5c, '\'
  198.   { 0x07, 0x0e, 0x02, 0x02, 0x02, 0x02, 0x02, 0x0e, 0x00 },   // 0x5d, ]
  199.   { 0x07, 0x04, 0x0a, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00 },   // 0x5e, ^
  200.   { 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00 },   // 0x5f, _
  201.   { 0x07, 0x04, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 },   // 0x60, `
  202.   { 0x07, 0x00, 0x0e, 0x01, 0x0d, 0x13, 0x13, 0x0d, 0x00 },   // 0x61, a
  203.   { 0x07, 0x10, 0x10, 0x10, 0x1c, 0x12, 0x12, 0x1c, 0x00 },   // 0x62, b
  204.   { 0x07, 0x00, 0x00, 0x00, 0x0e, 0x10, 0x10, 0x0e, 0x00 },   // 0x63, c
  205.   { 0x07, 0x01, 0x01, 0x01, 0x07, 0x09, 0x09, 0x07, 0x00 },   // 0x64, d
  206.   { 0x07, 0x00, 0x00, 0x0e, 0x11, 0x1f, 0x10, 0x0f, 0x00 },   // 0x65, e
  207.   { 0x07, 0x06, 0x09, 0x08, 0x1c, 0x08, 0x08, 0x08, 0x00 },   // 0x66, f
  208.   { 0x07, 0x00, 0x0e, 0x11, 0x13, 0x0d, 0x01, 0x01, 0x0e },   // 0x67, g
  209.   { 0x07, 0x10, 0x10, 0x10, 0x16, 0x19, 0x11, 0x11, 0x00 },   // 0x68, h
  210.   { 0x05, 0x00, 0x02, 0x00, 0x06, 0x02, 0x02, 0x07, 0x00 },   // 0x69, i
  211.   { 0x07, 0x00, 0x02, 0x00, 0x06, 0x02, 0x02, 0x12, 0x0c },   // 0x6a, j
  212.   { 0x07, 0x10, 0x10, 0x12, 0x14, 0x18, 0x14, 0x12, 0x00 },   // 0x6b, k
  213.   { 0x05, 0x06, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00 },   // 0x6c, l
  214.   { 0x07, 0x00, 0x00, 0x0a, 0x15, 0x15, 0x11, 0x11, 0x00 },   // 0x6d, m
  215.   { 0x07, 0x00, 0x00, 0x16, 0x19, 0x11, 0x11, 0x11, 0x00 },   // 0x6e, n
  216.   { 0x07, 0x00, 0x00, 0x0e, 0x11, 0x11, 0x11, 0x0e, 0x00 },   // 0x6f, o
  217.   { 0x07, 0x00, 0x00, 0x1c, 0x12, 0x12, 0x1c, 0x10, 0x10 },   // 0x70, p
  218.   { 0x07, 0x00, 0x00, 0x07, 0x09, 0x09, 0x07, 0x01, 0x01 },   // 0x71, q
  219.   { 0x07, 0x00, 0x00, 0x16, 0x19, 0x10, 0x10, 0x10, 0x00 },   // 0x72, r
  220.   { 0x07, 0x00, 0x00, 0x0f, 0x10, 0x0e, 0x01, 0x1e, 0x00 },   // 0x73, s
  221.   { 0x07, 0x08, 0x08, 0x1c, 0x08, 0x08, 0x09, 0x06, 0x00 },   // 0x74, t
  222.   { 0x07, 0x00, 0x00, 0x11, 0x11, 0x11, 0x13, 0x0d, 0x00 },   // 0x75, u
  223.   { 0x07, 0x00, 0x00, 0x11, 0x11, 0x11, 0x0a, 0x04, 0x00 },   // 0x76, v
  224.   { 0x07, 0x00, 0x00, 0x11, 0x11, 0x15, 0x15, 0x0a, 0x00 },   // 0x77, w
  225.   { 0x07, 0x00, 0x00, 0x11, 0x0a, 0x04, 0x0a, 0x11, 0x00 },   // 0x78, x
  226.   { 0x07, 0x00, 0x00, 0x11, 0x11, 0x0f, 0x01, 0x11, 0x0e },   // 0x79, y
  227.   { 0x07, 0x00, 0x00, 0x1f, 0x02, 0x04, 0x08, 0x1f, 0x00 },   // 0x7a, z
  228.   { 0x07, 0x06, 0x08, 0x08, 0x10, 0x08, 0x08, 0x06, 0x00 },   // 0x7b, {
  229.   { 0x07, 0x04, 0x04, 0x04, 0x00, 0x04, 0x04, 0x04, 0x00 },   // 0x7c, |
  230.   { 0x07, 0x0c, 0x02, 0x02, 0x01, 0x02, 0x02, 0x0c, 0x00 },   // 0x7d, }
  231.   { 0x07, 0x08, 0x15, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 },   // 0x7e, ~
  232.   { 0x07, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x00 }    // 0x7f, DEL
  233. };


  234. struct DateTime {
  235.   unsigned short second1, second2, second12, min1, min2, min12, hour1, hour2, hour12;
  236.   unsigned short day1, day2, day12, mon1, mon2, mon12, year1, year2, year12, WT;
  237. } MEZ;

  238. //*************************************************************************************************
  239. const unsigned short InitArr[7][2] = {
  240.   { 0x0C, 0x00 },    // display off
  241.   { 0x00, 0xFF },    // no LEDtest
  242.   { 0x09, 0x00 },    // BCD off
  243.   { 0x0F, 0x00 },    // normal operation
  244.   { 0x0B, 0x07 },    // start display
  245.   { 0x0A, 0x04 },    // brightness
  246.   { 0x0C, 0x01 }     // display on
  247. };
  248. //**************************************************************************************************
  249. void max7219_init()  //all MAX7219 init
  250. {
  251.   unsigned short i, j;
  252.   for (i = 0; i < 7; i++) {
  253.     digitalWrite(CS, LOW);
  254.     delayMicroseconds(1);
  255.     for (j = 0; j < anzMAX; j++) {
  256.       SPI.write(InitArr[i][0]);  //register
  257.       SPI.write(InitArr[i][1]);  //value
  258.     }
  259.     digitalWrite(CS, HIGH);
  260.   }
  261. }
  262. //**************************************************************************************************
  263. void max7219_set_brightness(unsigned short br)  //brightness MAX7219
  264. {
  265.   unsigned short j;
  266.   if (br < 16) {
  267.     digitalWrite(CS, LOW);
  268.     delayMicroseconds(1);
  269.     for (j = 0; j < anzMAX; j++) {
  270.       SPI.write(0x0A);  //register
  271.       SPI.write(br);    //value
  272.     }
  273.     digitalWrite(CS, HIGH);
  274.   }
  275. }
  276. //**************************************************************************************************
  277. void helpArr_init(void)  //helperarray init
  278. {
  279.   unsigned short i, j, k;
  280.   j = 0;
  281.   k = 0;
  282.   for (i = 0; i < anzMAX * 8; i++) {
  283.     helpArrPos[i] = (1 << j);   //bitmask
  284.     helpArrMAX[i] = k;
  285.     j++;
  286.     if (j > 7) {
  287.       j = 0;
  288.       k++;
  289.     }
  290.   }
  291. }
  292. //**************************************************************************************************
  293. void clear_Display()   //clear all
  294. {
  295.   unsigned short i, j;
  296.   for (i = 0; i < 8; i++)     //8 rows
  297.   {
  298.     digitalWrite(CS, LOW);
  299.     delayMicroseconds(1);
  300.     for (j = anzMAX; j > 0; j--) {
  301.       LEDarr[j - 1][i] = 0;       //LEDarr clear
  302.       SPI.write(i + 1);           //current row
  303.       SPI.write(LEDarr[j - 1][i]);
  304.     }
  305.     digitalWrite(CS, HIGH);
  306.   }
  307. }
  308. //*********************************************************************************************************
  309. void rotate_90() // for Generic displays
  310. {
  311.   for (uint8_t k = anzMAX; k > 0; k--) {

  312.     uint8_t i, j, m, imask, jmask;
  313.     uint8_t tmp[8] = {0, 0, 0, 0, 0, 0, 0, 0};
  314.     for (  i = 0, imask = 0x01; i < 8; i++, imask <<= 1) {
  315.       for (j = 0, jmask = 0x01; j < 8; j++, jmask <<= 1) {
  316.         if (LEDarr[k - 1][i] & jmask) {
  317.           tmp[j] |= imask;
  318.         }
  319.       }
  320.     }
  321.     for (m = 0; m < 8; m++) {
  322.       LEDarr[k - 1][m] = tmp[m];
  323.     }
  324.   }
  325. }
  326. //**************************************************************************************************
  327. void refresh_display() //take info into LEDarr
  328. {
  329.   unsigned short i, j;

  330. #ifdef ROTATE_90
  331.   rotate_90();
  332. #endif
  333.   for (i = 0; i < 8; i++)     //8 rows
  334.   {
  335.     digitalWrite(CS, LOW);
  336.     delayMicroseconds(1);
  337.     for (j = anzMAX; j > 0; j--) {
  338.       SPI.write(i + 1);  //current row
  339. #ifdef REVERSE_HORIZONTAL
  340.       SPI.setBitOrder(LSBFIRST);      // bitorder for reverse columns
  341. #endif

  342. #ifdef REVERSE_VERTICAL
  343.       SPI.write(LEDarr[j - 1][7 - i]);
  344. #else
  345.       SPI.write(LEDarr[j - 1][i]);
  346. #endif

  347. #ifdef REVERSE_HORIZONTAL
  348.       SPI.setBitOrder(MSBFIRST);      // reset bitorder
  349. #endif
  350.     }
  351.     digitalWrite(CS, HIGH);
  352.   }
  353. }
  354. //**************************************************************************************************
  355. void char2Arr(unsigned short ch, int PosX, short PosY) { //characters into arr
  356.   int i, j, k, l, m, o1, o2, o3, o4;  //in LEDarr
  357.   PosX++;
  358.   k = ch - 32;                        //ASCII position in font
  359.   if ((k >= 0) && (k < 96))           //character found in font
  360.   {
  361.     o4 = font1[k][0];                 //character width
  362.     o3 = 1 << (o4 - 2);
  363.     for (i = 0; i < o4; i++) {
  364.       if (((PosX - i <= maxPosX) && (PosX - i >= 0))
  365.           && ((PosY > -8) && (PosY < 8))) //within matrix?
  366.       {
  367.         o1 = helpArrPos[PosX - i];
  368.         o2 = helpArrMAX[PosX - i];
  369.         for (j = 0; j < 8; j++) {
  370.           if (((PosY >= 0) && (PosY <= j)) || ((PosY < 0) && (j < PosY + 8))) //scroll vertical
  371.           {
  372.             l = font1[k][j + 1];
  373.             m = (l & (o3 >> i));  //e.g. o4=7  0zzzzz0, o4=4  0zz0
  374.             if (m > 0)
  375.               LEDarr[o2][j - PosY] = LEDarr[o2][j - PosY] | (o1);  //set point
  376.             else
  377.               LEDarr[o2][j - PosY] = LEDarr[o2][j - PosY] & (~o1); //clear point
  378.           }
  379.         }
  380.       }
  381.     }
  382.   }
  383. }

  384. //**************************************************************************************************
  385. void timer50ms() {
  386.   static unsigned int cnt50ms = 0;
  387.   static unsigned int cnt1s = 0;
  388.   static unsigned int cnt1h = 0;
  389.   f_tckr50ms = true;
  390.   cnt50ms++;
  391.   if (cnt50ms == 20) {
  392.     f_tckr1s = true; // 1 sec
  393.     cnt1s++;
  394.     cnt50ms = 0;
  395.   }
  396.   if (cnt1s == 3600) { // 1h
  397.     f_tckr1h = true;
  398.     cnt1h++;
  399.     cnt1s = 0;
  400.   }
  401.   if (cnt1h == 24) { // 1d
  402.     f_tckr24h = true;
  403.     cnt1h = 0;
  404.   }
  405. }
  406. //**************************************************************************************************
  407. void WiFisetup() {
  408.   //WiFiManager
  409.   //Local intialization. Once its business is done, there is no need to keep it around
  410.   WiFiManager wifiManager;

  411.   //wifiManager.resetSettings();

  412.   wifiManager.setAPStaticIPConfig(IPAddress(10, 0, 1, 1), IPAddress(10, 0, 1, 1), IPAddress(255, 255, 255, 0));

  413.   //wifiManager.autoConnect("Wifi Clock");

  414.   // wifiManager.setTimeout(180);

  415.   wifiManager.setConfigPortalTimeout(60);         //1 minute

  416.   if (!wifiManager.autoConnect("Wifi Clock"))
  417.   {
  418.     Serial.println(F("Failed to connect. Reset and try again..."));
  419.     delay(3000);
  420.     ESP.reset();       //重置并重试
  421.     delay(5000);
  422.   }

  423.   //if you get here you have connected to the WiFi
  424.   digitalWrite(wf_led, LOW);   //blue led on if wifi connected

  425.   Serial.println("WiFi Connected!");
  426.   Serial.print("IP ssid: ");
  427.   Serial.println(WiFi.SSID());
  428.   Serial.print("IP addr: ");
  429.   Serial.println(WiFi.localIP());
  430. }
  431. //**************************************************************************************************
  432. void Otasetup() {

  433.   ArduinoOTA.onStart([]() {
  434.     Serial.println("OTA Update Start");
  435.   });

  436.   ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
  437.     Serial.print("Progress: ");
  438.     Serial.println((progress / (total / 100)));
  439.     //    clear_Display();
  440.     char2Arr('O', 45, 0);            //OTA
  441.     char2Arr('T', 39, 0);
  442.     char2Arr('A', 33, 0);
  443.     char2Arr('.', 25, 0);
  444.     char2Arr('.', 19, 0);
  445.     char2Arr('.', 13, 0);
  446.     refresh_display();
  447.   });

  448.   ArduinoOTA.onEnd([]() {
  449.     Serial.println("OTA End,Restart......");
  450.   });

  451.   ArduinoOTA.onError([](ota_error_t error) {
  452.     Serial.printf("Error[%u]: ", error);
  453.     if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
  454.     else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
  455.     else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
  456.     else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
  457.     else if (error == OTA_END_ERROR) Serial.println("End Failed");
  458.   });
  459.   ArduinoOTA.begin();
  460. }
  461. //**************************************************************************************************
  462. #ifdef LDR_SENSOR
  463. void Setintens()
  464. {
  465.   //  int intens = ((1024 - analogRead(A0LDR)) / 300);
  466.   int intens = ((analogRead(A0LDR) - 400) / 12);  //480-663 亮-暗
  467.     if (intens < 8) {
  468.       intens = 10;
  469.     }
  470.     else if (intens == 8 || intens == 9 || intens == 10 || intens == 11 )  {
  471.       intens = 8;
  472.     }
  473.     else if (intens == 12 || intens == 13 || intens == 14 || intens == 15)  {
  474.       intens = 5;
  475.     }
  476.     else if (intens == 16 || intens == 17 || intens == 18 || intens == 19)  {
  477.       intens = 3;
  478.     }
  479.     else if (intens > 19) {
  480.       intens = 1;                          //整理亮度值,值越大亮度越高
  481.     }

  482. #ifdef LDR_DEBUG
  483. Serial.print("A0LDR: ");
  484. Serial.print(analogRead(A0LDR));
  485. Serial.print(" intens: ");
  486. Serial.println(intens);
  487. #endif
  488. max7219_set_brightness(intens);
  489. }
  490. #endif
  491. //**************************************************************************************************
  492. void setup ()
  493. {
  494.   pinMode(wf_led, OUTPUT);    //wifi led
  495.   digitalWrite(wf_led, HIGH); // led off

  496.   pinMode(CS, OUTPUT);
  497.   digitalWrite(CS, HIGH);

  498.   Serial.begin(115200);        // most ESP-01's use 115200 but this could vary
  499.   SPI.begin();
  500.   helpArr_init();
  501.   max7219_init();
  502.   clear_Display();
  503.   tckr.attach(0.05, timer50ms);    // every 50 msec
  504. #ifdef LDR_SENSOR
  505.   Setintens();                     // set intensiteit naar LDR.
  506. #endif
  507. /*
  508.   char2Arr('.', 41, 0);            //LOGO
  509.   char2Arr('C', 37, 0);
  510.   char2Arr('L', 31, 0);
  511.   char2Arr('O', 25, 0);
  512.   char2Arr('C', 19, 0);
  513.   char2Arr('K', 13, 0);
  514.   char2Arr('.', 6, 0);
  515.   refresh_display();
  516. */
  517.   char2Arr('.', 41, 0);            //LOGO
  518.   char2Arr('H', 37, 0);
  519.   char2Arr('e', 31, 0);
  520.   char2Arr('l', 25, 0);
  521.   char2Arr('l', 19, 0);
  522.   char2Arr('o', 13, 0);
  523.   char2Arr('.', 6, 0);
  524.   refresh_display();
  525.   delay(1500);
  526.   
  527.   clear_Display();
  528.   char2Arr('W', 45, 0);            //WIFI
  529.   char2Arr('i', 38, 0);
  530.   char2Arr('F', 33, 0);
  531.   char2Arr('i', 27, 0);
  532.   char2Arr('.', 20, 0);
  533.   char2Arr('.', 13, 0);
  534.   char2Arr('.', 6, 0);
  535.   refresh_display();
  536.   WiFisetup();
  537.   timeClient.begin();              // Start the NTP UDP client
  538.   Otasetup();
  539. }

  540. void loop()
  541. {
  542.   unsigned int second1 = 0, second2 = 0, min1 = 0, min2 = 0, hour1 = 0, hour2 = 0;
  543.   unsigned int second11 = 0, second12 = 0, second21 = 0, second22 = 0;
  544.   unsigned int min11 = 0, min12 = 0, min21 = 0, min22 = 0;
  545.   unsigned int hour11 = 0, hour12 = 0, hour21 = 0, hour22 = 0;
  546.   signed int x = 0; //x1,x2;
  547.   signed int y = 0, y1 = 0, y2 = 0;
  548.   bool updown = false;
  549.   unsigned int sc1 = 0, sc2 = 0, sc3 = 0, sc4 = 0, sc5 = 0, sc6 = 0;
  550.   bool f_scrollend_y = false;
  551.   unsigned int f_scroll_x = false;

  552.   unsigned short year, day, month, hour, minute, second, week;

  553.   z_PosX = maxPosX;
  554.   d_PosX = -8;
  555.   //  x=0; x1=0; x2=0;

  556.   refresh_display();
  557.   updown = true;
  558.   if (updown == false) {
  559.     y2 = -9;
  560.     y1 = 8;
  561.   }
  562.   if (updown == true) { //scroll  up to down
  563.     y2 = 8;
  564.     y1 = -8;
  565.   }

  566.   while (true) {
  567.     yield();
  568.     ArduinoOTA.handle();       //ArduinoOTA
  569.     /*
  570.         if (f_tckr1h == true)        // check each hour if wifi is connected
  571.         {
  572.            if (WiFi.status() != WL_CONNECTED)
  573.            {
  574.              digitalWrite(wf_led,HIGH);   //led off
  575.            }
  576.            else
  577.            {
  578.              digitalWrite(wf_led,LOW);    //led on
  579.            }
  580.                 f_tckr1h == false;
  581.         }
  582.     */

  583.     if (f_tckr1s == true)            // flag 1second
  584.     {
  585.       if (WiFi.status() != WL_CONNECTED)
  586.       {
  587.         digitalWrite(wf_led, HIGH);         //led off
  588.         Serial.println("WiFi Disconnect!");
  589.       }
  590.       else
  591.       {
  592.         digitalWrite(wf_led, LOW);         //led on
  593.       }

  594.       int WiFi_status;
  595.       WiFi_status = digitalRead(wf_led);
  596.       if (WiFi_status) {
  597.         Serial.print("WiFi status: ");
  598.         Serial.println(WiFi_status);
  599.       }

  600. #ifdef LDR_SENSOR
  601.       Setintens();                     // set intensiteit naar LDR.
  602. #endif
  603.       if (timeClient.update()) { // update the NTP client and get the UNIX UTC timestamp
  604.         year = timeClient.getYear();
  605.         month = timeClient.getMonth();
  606.         day = timeClient.getDate();
  607.         week = timeClient.getDay();
  608.         hour = timeClient.getHours();
  609.         minute = timeClient.getMinutes();
  610.         second = timeClient.getSeconds();

  611.         MEZ.WT = week;
  612.         MEZ.second1 = second % 10;
  613.         MEZ.second2 = second / 10;
  614.         MEZ.second12 = second;
  615.         MEZ.min1 = minute % 10;
  616.         MEZ.min2 = minute / 10;
  617.         MEZ.min12 = minute;
  618.         MEZ.hour1 = hour % 10;
  619.         MEZ.hour2 = hour / 10;
  620.         MEZ.hour12 = hour;
  621.         MEZ.day12 = day;
  622.         MEZ.day1 = day % 10;
  623.         MEZ.day2 = day / 10;
  624.         MEZ.mon12 = month;
  625.         MEZ.mon1 = month % 10;
  626.         MEZ.mon2 = month / 10;
  627.         MEZ.year12 = year;
  628.         MEZ.year1 = year % 10;          //Single
  629.         MEZ.year2 = year / 10 % 10;     //Ten
  630.       }

  631. #ifdef DATATIME_PRINT
  632.       Serial.print(MEZ.year12);
  633.       Serial.print("-");
  634.       Serial.print(MEZ.mon12);
  635.       Serial.print("-");
  636.       Serial.print(MEZ.day12);
  637.       Serial.print(" ");
  638.       Serial.print(MEZ.hour12);
  639.       Serial.print(":");
  640.       Serial.print(MEZ.min12);
  641.       Serial.print(":");
  642.       Serial.print(MEZ.second12);
  643.       Serial.print(",");
  644.       Serial.println(MEZ.WT);
  645. #endif

  646.       second1 = MEZ.second1;
  647.       second2 = MEZ.second2;
  648.       min1 = MEZ.min1;
  649.       min2 = MEZ.min2;
  650.       hour1 = MEZ.hour1;
  651.       hour2 = MEZ.hour2;
  652.       y = y2;                                 //scroll updown
  653.       sc1 = 1;
  654.       second1++;
  655.       if (second1 == 10) {
  656.         sc2 = 1;
  657.         second2++;
  658.         second1 = 0;
  659.       }
  660.       if (second2 == 6) {
  661.         min1++;
  662.         second2 = 0;
  663.         sc3 = 1;
  664.       }
  665.       if (min1 == 10) {
  666.         min2++;
  667.         min1 = 0;
  668.         sc4 = 1;
  669.       }
  670.       if (min2 == 6) {
  671.         hour1++;
  672.         min2 = 0;
  673.         sc5 = 1;
  674.       }
  675.       if (hour1 == 10) {
  676.         hour2++;
  677.         hour1 = 0;
  678.         sc6 = 1;
  679.       }
  680.       if ((hour2 == 2) && (hour1 == 4)) {
  681.         hour1 = 0;
  682.         hour2 = 0;
  683.         sc6 = 1;
  684.       }

  685.       second11 = second12;
  686.       second12 = second1;
  687.       second21 = second22;
  688.       second22 = second2;
  689.       min11 = min12;
  690.       min12 = min1;
  691.       min21 = min22;
  692.       min22 = min2;
  693.       hour11 = hour12;
  694.       hour12 = hour1;
  695.       hour21 = hour22;
  696.       hour22 = hour2;
  697.       f_tckr1s = false;
  698. //    if (MEZ.second12 == 20 || MEZ.second12 == 40 || MEZ.second12 == 00) //设置循环显示时间点
  699.       if (MEZ.second12 == 40) //设置循环显示时间点,40s时
  700.         f_scroll_x = true;
  701.     } // end 1s

  702.     if (f_tckr50ms == true) {
  703.       f_tckr50ms = false;
  704.       if (f_scroll_x == true) {
  705.         z_PosX++;
  706.         d_PosX++;
  707.         if (d_PosX == 86) //         char2Arr(WT_arr[MEZ.WT][2], d_PosX - 80, 0);
  708.           z_PosX = 0;
  709.         if (z_PosX == maxPosX) {
  710.           f_scroll_x = false;
  711.           d_PosX = -8;
  712.         }
  713.       }
  714.       if (sc1 == 1) {
  715.         if (updown == 1)
  716.           y--;
  717.         else
  718.           y++;
  719.         char2Arr(48 + second12, z_PosX - 42, y);
  720.         char2Arr(48 + second11, z_PosX - 42, y + y1);
  721.         if (y == 0) {
  722.           sc1 = 0;
  723.           f_scrollend_y = true;
  724.         }
  725.       }
  726.       else
  727.         char2Arr(48 + second1, z_PosX - 42, 0);

  728.       if (sc2 == 1) {
  729.         char2Arr(48 + second22, z_PosX - 36, y);
  730.         char2Arr(48 + second21, z_PosX - 36, y + y1);
  731.         if (y == 0)
  732.           sc2 = 0;
  733.       }
  734.       else
  735.         char2Arr(48 + second2, z_PosX - 36, 0);

  736.       char2Arr(':', z_PosX - 32, 0);

  737.       if (sc3 == 1) {
  738.         char2Arr(48 + min12, z_PosX - 25, y);
  739.         char2Arr(48 + min11, z_PosX - 25, y + y1);
  740.         if (y == 0)
  741.           sc3 = 0;
  742.       }
  743.       else
  744.         char2Arr(48 + min1, z_PosX - 25, 0);

  745.       if (sc4 == 1) {
  746.         char2Arr(48 + min22, z_PosX - 19, y);
  747.         char2Arr(48 + min21, z_PosX - 19, y + y1);
  748.         if (y == 0)
  749.           sc4 = 0;
  750.       }
  751.       else
  752.         char2Arr(48 + min2, z_PosX - 19, 0);

  753.       char2Arr(':', z_PosX - 15 + x, 0);

  754.       if (sc5 == 1) {
  755.         char2Arr(48 + hour12, z_PosX - 8, y);
  756.         char2Arr(48 + hour11, z_PosX - 8, y + y1);
  757.         if (y == 0)
  758.           sc5 = 0;
  759.       }
  760.       else
  761.         char2Arr(48 + hour1, z_PosX - 8, 0);

  762.       if (sc6 == 1) {
  763.         char2Arr(48 + hour22, z_PosX - 2, y);
  764.         char2Arr(48 + hour21, z_PosX - 2, y + y1);
  765.         if (y == 0)
  766.           sc6 = 0;
  767.       }
  768.       else
  769.         char2Arr(48 + hour2, z_PosX - 2, 0);

  770. #ifdef CHINESE_CALENDAR
  771.       char2Arr('2', d_PosX - 5, 0);                     //year
  772.       char2Arr('0', d_PosX - 11, 0);
  773.       char2Arr(48 + MEZ.year2, d_PosX - 17, 0);
  774.       char2Arr(48 + MEZ.year1, d_PosX - 23, 0);
  775.       char2Arr(M_arr[MEZ.mon12 - 1][0], d_PosX - 30, 0);
  776.       char2Arr(M_arr[MEZ.mon12 - 1][1], d_PosX - 35, 0);
  777.       char2Arr(M_arr[MEZ.mon12 - 1][2], d_PosX - 41, 0);
  778.       char2Arr(M_arr[MEZ.mon12 - 1][3], d_PosX - 48, 0);
  779.       char2Arr(48 + MEZ.day2, d_PosX - 53, 0);           //day
  780.       char2Arr(48 + MEZ.day1, d_PosX - 59, 0);
  781.       char2Arr(WT_arr[MEZ.WT][0], d_PosX - 68, 0);        //day of the week
  782.       char2Arr(WT_arr[MEZ.WT][1], d_PosX - 74, 0);
  783.       char2Arr(WT_arr[MEZ.WT][2], d_PosX - 80, 0);
  784. #else
  785.       char2Arr(WT_arr[MEZ.WT][0], d_PosX - 5, 0);        //day of the week
  786.       char2Arr(WT_arr[MEZ.WT][1], d_PosX - 11, 0);
  787.       char2Arr(WT_arr[MEZ.WT][2], d_PosX - 17, 0);
  788.       char2Arr(WT_arr[MEZ.WT][3], d_PosX - 23, 0);
  789.       char2Arr(48 + MEZ.day2, d_PosX - 27, 0);           //day
  790.       char2Arr(48 + MEZ.day1, d_PosX - 33, 0);
  791.       char2Arr(M_arr[MEZ.mon12 - 1][0], d_PosX - 39, 0); //month
  792.       char2Arr(M_arr[MEZ.mon12 - 1][1], d_PosX - 43, 0);
  793.       char2Arr(M_arr[MEZ.mon12 - 1][2], d_PosX - 49, 0);
  794.       char2Arr(M_arr[MEZ.mon12 - 1][3], d_PosX - 55, 0);
  795.       char2Arr(M_arr[MEZ.mon12 - 1][4], d_PosX - 61, 0);
  796.       char2Arr('2', d_PosX - 68, 0);                     //year
  797.       char2Arr('0', d_PosX - 74, 0);
  798.       char2Arr(48 + MEZ.year2, d_PosX - 80, 0);
  799.       char2Arr(48 + MEZ.year1, d_PosX - 86, 0);
  800. #endif
  801.       refresh_display(); //alle 50ms
  802.       if (f_scrollend_y == true) {
  803.         f_scrollend_y = false;
  804.       }
  805.     } //end 50ms
  806.     if (y == 0) {
  807.       // do something else
  808.     }
  809.   }  //end while(true)
  810.   //this section can not be reached
  811. }
复制代码


代码下载:
MatrixClock-ota.zip (7.3 KB, 下载次数: 115)

库下载:(特别说明:<NTPClient.h>库增加了直接获取 year, month, day函数,库管理器联网下载的库不可用)
NTPClient.zip (7.13 KB, 下载次数: 134)


一些配置说明:
  1. #define NTP_OFFSET     8*3600                    //+8h,北京时间
  2. #define NTP_INTERVAL   12*60*60*1000             //12*60*60*1000  12 hours 更新
  3. #define NTP_ADDRESS  "ntp1.aliyun.com"
  4. //#define NTP_ADDRESS    "time1.cloud.tencent.com"
复制代码
时区调整,北京时间+8
时间更新间隔,代码中是12小时
NTP服务器地址:阿里云,可选腾讯等

  1. #define wf_led  2      // 0,D3
  2. #define CS             15     // D8=cs Pin(SPI) D5=CLK, D7=DI
复制代码
WIFI状态指示LED脚,MAX7219 CS脚引脚定义


  1. #define DATATIME_PRINT
  2. #define CHINESE_CALENDAR                            //中国日历显示方式 1900-01-01,星期
  3. #define LDR_SENSOR
  4. #define LDR_DEBUG
复制代码
打印时间宏定义
中国日历宏定义,注释掉为西方国家日期格式:12 Mar 2019.
LDR光线检测宏定义,注释掉为不使用LDR光线检测。
LDR光线检测调试宏定义,用于使用不同LDR时打印光线对应亮度,调试。

  1.   if (!wifiManager.autoConnect("Wifi Clock"))
复制代码
同样的,WIFI热点名称定义

  1. #ifdef LDR_SENSOR
  2. void Setintens()
  3. {
  4.   //  int intens = ((1024 - analogRead(A0LDR)) / 300);
  5.   int intens = ((analogRead(A0LDR) - 400) / 12);  //480-663 亮-暗
  6.     if (intens < 8) {
  7.       intens = 10;
  8.     }
  9.     else if (intens == 8 || intens == 9 || intens == 10 || intens == 11 )  {
  10.       intens = 8;
  11.     }
  12.     else if (intens == 12 || intens == 13 || intens == 14 || intens == 15)  {
  13.       intens = 5;
  14.     }
  15.     else if (intens == 16 || intens == 17 || intens == 18 || intens == 19)  {
  16.       intens = 3;
  17.     }
  18.     else if (intens > 19) {
  19.       intens = 1;                          //整理亮度值,值越大亮度越高
  20.     }

  21. #ifdef LDR_DEBUG
  22. Serial.print("A0LDR: ");
  23. Serial.print(analogRead(A0LDR));
  24. Serial.print(" intens: ");
  25. Serial.println(intens);
  26. #endif
  27. max7219_set_brightness(intens);
  28. }
  29. #endif
复制代码
LDR光线检测调整亮度函数,不同的LDR需要细调。

  1. /*
  2.   char2Arr('.', 41, 0);            //LOGO
  3.   char2Arr('C', 37, 0);
  4.   char2Arr('L', 31, 0);
  5.   char2Arr('O', 25, 0);
  6.   char2Arr('C', 19, 0);
  7.   char2Arr('K', 13, 0);
  8.   char2Arr('.', 6, 0);
  9.   refresh_display();
  10. */
  11.   char2Arr('.', 41, 0);            //LOGO
  12.   char2Arr('H', 37, 0);
  13.   char2Arr('e', 31, 0);
  14.   char2Arr('l', 25, 0);
  15.   char2Arr('l', 19, 0);
  16.   char2Arr('o', 13, 0);
  17.   char2Arr('.', 6, 0);
  18.   refresh_display();
  19.   delay(1500);
  20.   
  21.   clear_Display();
  22.   char2Arr('W', 45, 0);            //WIFI
  23.   char2Arr('i', 38, 0);
  24.   char2Arr('F', 33, 0);
  25.   char2Arr('i', 27, 0);
  26.   char2Arr('.', 20, 0);
  27.   char2Arr('.', 13, 0);
  28.   char2Arr('.', 6, 0);
  29.   refresh_display();
  30.   WiFisetup();
  31.   timeClient.begin();              // Start the NTP UDP client
  32.   Otasetup();
复制代码
LOGO显示,可自由调整,注意字符显示的位置及数量。

  1.       if (MEZ.second12 == 40) //设置循环显示时间点,40s时
复制代码
滚动显示日期、星期的时间点,代码中为40秒时滚动显示,滚动时间大概8秒左右。


视频效果,来自坛友仿制:https://www.mydigit.cn/thread-294319-1-1.html
WiFi点阵时钟视频效果.mp4 (1.05 MB, 下载次数: 3)



补充内容 (2022-1-20 10:03):
52#  有lupo88坛友修改的共阳点阵程序,可参考, 55#为文中PCB原文件,EDA软件为pads2005.

打赏

参与人数 3家元 +90 收起 理由
pcsjh + 30 優秀文章
qingkong + 30 一个字 赞
家睦 + 30

查看全部打赏

发表于 2019-12-25 19:13:28 来自手机浏览器 | 显示全部楼层
编译环境都搞不了的表示就看看了…
回复 支持 反对

使用道具 举报

发表于 2019-12-25 20:16:25 | 显示全部楼层
触景情伤 发表于 2019-12-25 19:13
编译环境都搞不了的表示就看看了…

新手玩ESP8266用阿尔杜一诺的人最多资源也最多,其他的资源少些,我弄了一阵子lua,虽然wifi校时也没问题但是因为没能深入就撂下了,模块一直在吃灰。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-12-26 06:58:09 来自手机浏览器 | 显示全部楼层
触景情伤 发表于 2019-12-25 19:13
编译环境都搞不了的表示就看看了…

Arduino资源很多,精华就是各种库,不需要很复杂的环境搭建,官网的版本安装外加ESP8266补丁安装就好,不需要设置路径获取环境,因为连接的外网有时不稳定而安装失败。
回复 支持 反对

使用道具 举报

发表于 2019-12-26 09:04:25 | 显示全部楼层
最近我也在做这个,楼主做的真好~
回复 支持 反对

使用道具 举报

发表于 2019-12-26 16:44:47 | 显示全部楼层
正好手上有控制板和8*32的屏想仿制1个,请教要改哪里,刚接触8266
回复 支持 反对

使用道具 举报

发表于 2019-12-26 16:56:25 | 显示全部楼层
手上正好有8266模块和8*32的屏,想仿制一个,请教需要修改哪些位置
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-12-26 17:53:15 | 显示全部楼层
cykhyk 发表于 2019-12-26 16:56
手上正好有8266模块和8*32的屏,想仿制一个,请教需要修改哪些位置
  1. #define anzMAX         6      // number of led matrix Modules
复制代码
修改为(未验证 ):#define anzMAX  4

回复 支持 反对

使用道具 举报

发表于 2019-12-27 08:18:06 | 显示全部楼层
zengcym 发表于 2019-12-26 17:53
修改为(未验证 ):#define anzMAX  4

仿制成功,因屏幕比较小没法显示秒,谢谢楼主分享。
回复 支持 反对

使用道具 举报

发表于 2020-1-9 19:27:47 | 显示全部楼层
不错,感谢lz
试验一个看看
回复 支持 反对

使用道具 举报

发表于 2020-1-9 19:30:16 | 显示全部楼层
网上看到一个用8*32的点阵屏幕,秒用小字显示的,可以节省2块点阵屏,看起来也听美观的。不过那个加上断网还显示的芯片。
lz能不能在这个基础上改改代码也搞一个。
淘宝关键字“hack实验室”
回复 支持 反对

使用道具 举报

发表于 2020-1-9 21:41:03 | 显示全部楼层
zengcym 发表于 2019-12-26 17:53
修改为(未验证 ):#define anzMAX  4

我试了有点问题,最左边多了2个点。
lz能不能搞成4块点阵屏幕显示秒的。

4块点阵屏读秒

4块点阵屏读秒



另外建议把星期几的英文改成大写数字哇,这样一眼就看懂了
回复 支持 反对

使用道具 举报

发表于 2020-1-9 23:00:40 | 显示全部楼层
muziwenwu 发表于 2020-1-9 21:41
我试了有点问题,最左边多了2个点。
lz能不能搞成4块点阵屏幕显示秒的。

亚克力哪里买的?老铁?给个链接。
我也在做这个,已经基本成功。
回复 支持 反对

使用道具 举报

发表于 2020-1-10 01:38:07 来自手机浏览器 | 显示全部楼层
这是什么字体?还挺好看的
回复 支持 反对

使用道具 举报

发表于 2020-1-10 23:48:38 | 显示全部楼层
亚克力找tb定制啊,量下尺寸
回复 支持 反对

使用道具 举报

发表于 2020-1-12 19:14:03 | 显示全部楼层
MAX7219 CS脚引脚定义 可以修改吗 怎么改呢 楼主
回复 支持 反对

使用道具 举报

发表于 2020-1-15 14:05:05 | 显示全部楼层
pcb是什么软件?AD09打不开啊
回复 支持 反对

使用道具 举报

发表于 2020-1-22 20:36:11 | 显示全部楼层
厉害了厉害了厉害了厉害了厉害了厉害了厉害了
回复 支持 反对

使用道具 举报

发表于 2020-2-21 15:12:52 | 显示全部楼层
OTA怎么弄,没弄明白,新人求指教,谢谢
回复 支持 反对

使用道具 举报

发表于 2020-2-25 12:12:58 | 显示全部楼层
本帖最后由 fryefryefrye 于 2020-2-25 12:14 编辑
muziwenwu 发表于 2020-1-9 21:41
我试了有点问题,最左边多了2个点。
lz能不能搞成4块点阵屏幕显示秒的。

星期这个东西,写成阿拉伯数字,感觉太山寨了。特别是周日,你说显示多少?0,7还是8?要不就给个16*16的点阵,显示汉字。
我自己做的钟,也是显示英文的。都写代码的人了,这点英语应该没问题吧。
回复 支持 反对

使用道具 举报

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

本版积分规则

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

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2024-4-24 03:56 , Processed in 0.265200 second(s), 14 queries , Redis On.

Powered by Discuz!

© 2006-2023 smzj.net

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