23浏览
查看: 23|回复: 2

[项目] 【Arduino 动手做】带 4x64 LED 矩阵的 Arduino Nano Clock (新...

[复制链接]
代码体积小,硬件简单。改进版本现已推出。

概述
在几米远的房间里读取时钟显示需要这样的 LED 矩阵显示器。
以优惠的价格购买了 4 单元显示器后,我在 Hackster 上查看了可用的项目:有几个用于 Arduino Nano 的项目。如果您想同时查看小时、分钟和秒:只有少数项目有效,因为您需要比每个数字 5x7 像素的广泛可用的数字更小的数字。一种选择是使用 MD_Parola 库,但代码大小对于简单的 clock来说太大了。另一个测试选项是 Max72xxPanel 库,但这太旧了,需要调用其他库。最后,该项目基于基本接口库 MD_MAX722XX,包含在所有其他接口库中。
此站点的评论使我回顾了硬件方面和代码。
- 有许多名为 DS3231 的库。我使用这个:http://www.rinkydinkelectronics.com/library.php?id=73
DS3231 I2C 实时时钟的 Arduino/chipKit 库版权所有 (C)2015 Rinky-Dink Electronics, Henning Karlsen.版权所有
- 首先:LED 矩阵显示。市面上有几种型号,所以很有可能上传这段代码后显示屏会显示奇怪的东西。解决方案:从 “MD_MAX72xx_lib.h” 库 “MD_MAX72xx_HW_Mapper.ino” 上传此示例并找到您的硬件型号。在我的代码中,模型被定义:#define HARDWARE_TYPE MD_MAX72XX::ICSTATION_HW,但在您设置正确的模型之前,这可能不起作用!
- 漂亮的小秒针最近没有出现吗?现在 (v2),这些秒的字体包含在代码中,因此无需更改任何其他库。
- 由于 Arduino 更新,出现较长的编译警告列表。现在,月份位于二维 char 数组中,不再使用指针。任何其他警告都来自 DS3231.h 库,但可以忽略。
- 闪烁的点现在只有 2 个点!准确的秒数使用我的 3x5 字体显示在 “hh:mm” 之后。此外,列点 “:” 几乎每秒闪烁两次,只是为了表明它是活的!
- Answering a request :时间每分钟显示 53 秒,最后 7 秒显示日期和温度。
- 如果您在 loop() 中取消注释两行,也可以显示星期几。在这种情况下,您可能希望将 53 秒的间隔减少到 51 秒。
- 如果您更喜欢 12 小时格式,请参阅我的一个较早的答案。
- 可以在 Arduino 串行监视器中设置 RTC 时间,方法是在输入区域 DD/MM/YYYY hh:mm:ss(不要忘记两者之间的空格)并按 Enter/Send。只要连接了 USB 电缆并且 Serial Monitor 正常工作(正确的 COM 和波特率),就可以执行此作。
新代码使用 13558 字节 (44%) 和 372 字节 (18%) 作为变量,因此它更短一些!
日期显示为 “dd Mon” 和室温(以 deg 为单位)。摄氏度(使用 RTC 内部传感器估算)显示在单独的页面上。亮度由光敏电阻控制。但是,即使没有光传感器,该代码也可以正常工作。

【Arduino 动手做】带 4x64 LED 矩阵的 Arduino Nano Clock (新...图2

【Arduino 动手做】带 4x64 LED 矩阵的 Arduino Nano Clock (新...图1

【Arduino 动手做】带 4x64 LED 矩阵的 Arduino Nano Clock (新...图3

【Arduino 动手做】带 4x64 LED 矩阵的 Arduino Nano Clock (新...图5

【Arduino 动手做】带 4x64 LED 矩阵的 Arduino Nano Clock (新...图4



驴友花雕  中级技神
 楼主|

发表于 3 小时前

【Arduino 动手做】带 4x64 LED 矩阵的 Arduino Nano Clock

项目代码

  1. /*  Arduino Nano DS3231 clock with LED Matrix 4x(8x8) SPI
  2. *  Version 2 - updated 15/05/2-21
  3. *  Arduino Nano 5V logic - 32kB prog. space  
  4. *  Tools:Board: Arduino Nano; Processor: ATmega328P (Old Bootloader)!!
  5. *  LED Matrix 4x(8x8) SPI with connector on the right side (last module)
  6. *  https://www.banggood.com/MAX7219-Dot-Matrix-Module-4-in-1-Display-For-Arduino-p-1072083.html?rmmds=myorder&cur_warehouse=CN
  7. *  
  8. *  CONNECTIONS:
  9. *  >> LCD 4x64   -> Arduino Nano: (using Hardware SPI):   
  10. *       5V            -> 5V pin
  11. *       GND           -> GND pin
  12. *     CLK_PIN        ->  13  // or SCK
  13. *    DATA_PIN        ->  11  // or MOSI
  14. *      CS_PIN        ->  10  // or SS   
  15. *      
  16. *  >> DS3231 RTC -> Arduino Nano:
  17. *       SDA (DAT)     -> A4
  18. *       SCL (CLK)     -> A5
  19. * Inspired by : 1) Arduino Clock by AnthoTRONICS Last edit: March 22,2019
  20. * but without MD_parola because of its large footprint! New getdate function.
  21. * 2) Simplest UNO Digital Clock Ever by plouc68000:
  22. * https://create.arduino.cc/projecthub/plouc68000/simplest-uno-digital-clock-ever-4613aa?ref=user&ref_id=680368&offset=1
  23. * 3) LEDDotMatrixClock.ino by Leonardo Sposina, but here without "Max72xxPanel.h"
  24. * https://github.com/leonardosposina/arduino-led-dot-matrix-clock/blob/master/LEDDotMatrixClock/LEDDotMatrixClock.ino
  25. * Not using Max72xxPanel.h, but small size digits are stll used. Small footprint code here.
  26. *
  27. * project: 113558 bytes (44%); variables 372 bytes (17%)
  28. * Author: MVP https://www.hackster.io/M-V-P
  29. */
  30. #include <SPI.h>
  31. #include "DS3231.h"
  32. #include "MD_MAX72xx_lib.h"
  33. //#include "Font_Data.h"
  34. DS3231 rtc(SDA, SCL);     // Real time clock
  35. const byte LDR_PIN = A2; // LDR Sensor pin
  36. #define MAX_DEVICES  4
  37. // Define pins
  38. #define CLK_PIN   13  // or SCK
  39. #define DATA_PIN  11  // or MOSI
  40. #define CS_PIN    10  // or SS
  41. // Define below your LED matrix hardware model:
  42. //#define HARDWARE_TYPE MD_MAX72XX::ICSTATION_HW
  43. #define HARDWARE_TYPE MD_MAX72XX::FC16_HW
  44. #define USE_NEW_FONT 1
  45. #define BUF_SIZE      20  // text buffer size
  46. #define CHAR_SPACING  1   // pixels between characters
  47. char buf[BUF_SIZE], secs[4];
  48. uint8_t hh, mm, ss, dots;
  49. // Definition of the small fonts:
  50. uint8_t Font3x5 [ 10 ][ 3 ]={
  51.   { 248, 136, 248},   // 48 0
  52.   {144, 248, 128},   // 49 1
  53.   {200, 168, 184},   // 50 2
  54.   {136, 168, 248},   // 51 3
  55.   {112, 72, 224},    // 52 4
  56.   {184, 168, 232},   // 53 5
  57.   {248, 168, 232},   // 54 6
  58.   {8, 232, 24},      // 55 7
  59.   {248, 168, 248},   // 56 8
  60.   {184, 168, 248}};   // 57 9
  61. char months[12][4]= {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
  62. char* wday;
  63. // SPI hardware interface
  64. // Max72xxPanel matrix = Max72xxPanel(CS_PIN, H_DISPLAYS, V_DISPLAYS);
  65. MD_MAX72XX matrix = MD_MAX72XX(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
  66. const byte WAIT = 100;
  67. const byte SPACER = 1;
  68. byte FONT_WIDTH;
  69. bool timeset=false;
  70. void adjustClock(String data) {
  71.   byte _day = data.substring(0,2).toInt();
  72.   byte _month = data.substring(3,5).toInt();
  73.   int _year = data.substring(6,10).toInt();
  74.   byte _hour = data.substring(11,13).toInt();
  75.   byte _min = data.substring(14,16).toInt();
  76.   byte _sec = data.substring(17,19).toInt();
  77.   rtc.setTime(_hour, _min, _sec);
  78.   rtc.setDate(_day, _month, _year);
  79.   Serial.println(F(">> Datetime successfully set!"));
  80.   timeset=true;
  81. }
  82. byte ledintensitySelect(int light) {
  83.   byte _value = 0;
  84.   if (light >= 0 && light <= 127) {
  85.     _value = 12;
  86.   } else if (light >= 128 && light <= 319) {
  87.     _value = 3;
  88.   } else if (light >= 320 && light <= 512) {
  89.     _value = 0;
  90.   }
  91.   return _value;
  92. };
  93. void printText(uint8_t modStart, uint8_t modEnd, char *pMsg)
  94. // Print the text string to the LED matrix modules specified.
  95. // Message area is padded with blank columns after printing.
  96. {
  97.   uint8_t   state = 0;
  98.   uint8_t   curLen;
  99.   uint16_t  showLen;
  100.   uint8_t   cBuf[FONT_WIDTH];
  101.   int16_t   col = ((modEnd + 1) * COL_SIZE) - 1;
  102.   matrix.control(modStart, modEnd, MD_MAX72XX::UPDATE, MD_MAX72XX::OFF);
  103.   do     // finite state machine to print the characters in the space available
  104.   {
  105.     switch(state)
  106.     {
  107.       case 0: // Load the next character from the font table
  108.         // if we reached end of message, reset the message pointer
  109.         if (*pMsg == '\0')
  110.         {
  111.           showLen = col - (modEnd * COL_SIZE);  // padding characters
  112.           state = 2;
  113.           break;
  114.         }
  115.         // retrieve the next character form the font file
  116.         showLen = matrix.getChar(*pMsg++, sizeof(cBuf)/sizeof(cBuf[0]), cBuf);
  117.         curLen = 0;
  118.         state++;
  119.         // !! deliberately fall through to next state to start displaying
  120.       case 1: // display the next part of the character
  121.         matrix.setColumn(col--, cBuf[curLen++]);
  122.         // done with font character, now display the space between chars
  123.         if (curLen == showLen)
  124.         {
  125.           showLen = CHAR_SPACING;
  126.           state = 2;
  127.         }
  128.         break;
  129.       case 2: // initialize state for displaying empty columns
  130.         curLen = 0;
  131.         state++;
  132.         // fall through
  133.       case 3:  // display inter-character spacing or end of message padding (blank columns)
  134.         matrix.setColumn(col--, 0);
  135.         curLen++;
  136.         if (curLen == showLen)
  137.           state = 0;
  138.         break;
  139.       default:
  140.         col = -1;   // this definitely ends the do loop
  141.     }
  142.   } while (col >= (modStart * COL_SIZE));
  143.   matrix.control(modStart, modEnd, MD_MAX72XX::UPDATE, MD_MAX72XX::ON);
  144. }
  145. void setup() {
  146.   pinMode(LDR_PIN, INPUT_PULLUP);
  147.   Serial.begin(9600);
  148.   Serial.println(F(">> Arduino 32x8 LED Dot Matrix Clock!"));
  149.   Serial.println(F(">> Use <dd/mm/yyyy hh:mm:ss> format to set clock's date and hour!"));
  150.   rtc.begin();
  151.   matrix.begin();
  152.   matrix.clear();
  153.   FONT_WIDTH= 5 + SPACER; // The font width is 5 pixels  
  154.   matrix.control(MD_MAX72XX::INTENSITY, 2);; // Use a value between 0 and 15 for brightness
  155.   rtc.setDOW();     // Required for a new RTC
  156. }
  157. void getDate()
  158. // Date Setup: Code for reading clock date
  159. {
  160.   String dts = rtc.getDateStr();    // Get dd/mm/yyyy string
  161.   String dds=dts.substring(0,2);    // Extract date
  162.   String mms=dts.substring(3,5);    // Extract month
  163.   int mm=mms.toInt();               // Convert to month number
  164.   dds.concat(" ");
  165.   dds.concat(String(months[mm-1])); // Rebuild date string as "dd Mmm"
  166.   dds.toCharArray(buf,sizeof(buf)); // return buffer
  167.   wday = rtc.getDOWStr(2);
  168. }
  169. void getHour()
  170. // Date Setup: Code for reading clock date
  171. { String dts = rtc.getTimeStr();    // Get hh:mm:ss string
  172.   String hhs=dts.substring(0,2);    // Extract hour
  173.   String mms=dts.substring(3,5);    // Extract minutes
  174.   hh=hhs.toInt();               // Convert to number
  175.   mm=mms.toInt();               // Convert to number mm
  176.   ss=(dts.substring(6,8)).toInt();  // Extract seconds as number
  177.   
  178.   if (hh >= 0 && hh < 10)  dots=7;
  179.   if (hh > 9 && hh < 20)  dots=11;
  180.   if (hh > 19 && hh < 25) dots=13;
  181.   if (hh%10 == 1)         dots-=2;
  182.   
  183.   //String outmsg=dts.substring(0,5);    // Extract hh:mm (optional)
  184.   String outmsg=String(hh);              // Extract h if h<10
  185.   // outmsg.concat(":");                    // add : but on 2 columns!!
  186.   outmsg.concat(char(124));              // add 1 full column between numbers
  187.   outmsg.concat(dts.substring(3,5));     // add mm
  188.   outmsg.toCharArray(buf,BUF_SIZE);
  189. }
  190. // New version of function, using the small embedded fonts
  191. void showsec(uint8_t secs)
  192. { uint8_t secs1=secs%10;
  193.   uint8_t secs2=secs/10;
  194.   for (uint8_t k=0; k<3; k++){
  195.     matrix.setColumn(MAX_DEVICES*8-26-k,Font3x5 [secs2][k]);
  196.     matrix.setColumn(MAX_DEVICES*8-30-k,Font3x5 [secs1][k]);  
  197.   }
  198. }
  199. void loop() {
  200.   byte ledIntensity = ledintensitySelect(analogRead(LDR_PIN));
  201.   matrix.control(MD_MAX72XX::INTENSITY, ledIntensity);; // Use a value between 0 and 15 for brightness
  202.   getHour();                      // Read time from RTC
  203.   printText(0,MAX_DEVICES-1,buf); // Show hh|mm from buf
  204.   matrix.setColumn(MAX_DEVICES*8-dots,0); // Clear the |
  205.   unsigned long inst =millis();   // mark this moment
  206.   while (ss < 53){                // First 53 seconds of each minute show time
  207.     while (millis() - inst > 1000){
  208.       inst =millis();
  209.       ss++;                       // Increase seconds
  210.       showsec(ss);                // Show seconds
  211.       for (uint8_t i = 0; i < 2; i++){
  212.         matrix.setColumn(MAX_DEVICES*8-dots,36); // Blinking two dots:
  213.         delay(240);
  214.         matrix.setColumn(MAX_DEVICES*8-dots,0);
  215.         delay(240);
  216.       }     
  217.     }
  218.   }
  219.   // Then "time" is scrolling upwards:
  220.   for (uint8_t i=0; i<8; i++){
  221.     matrix.transform(MD_MAX72XX::TSU);
  222.     delay(3*WAIT);
  223.   }
  224.   // Write the current date:
  225.   getDate();
  226.   printText(0,MAX_DEVICES-1,buf);
  227.   delay(20*WAIT);
  228.   // Write the week day (if uncommented):
  229.   //printText(0,MAX_DEVICES-1,wday);
  230.   //delay(20*WAIT);
  231.   // Write the estimated room temperature from the RTC sensor
  232.   int temp = rtc.getTemp();
  233.   temp=temp-1;                             // Offset -1 C
  234.   String outmsg=String(temp);
  235.   outmsg.concat(" C");
  236.   outmsg.toCharArray(buf,BUF_SIZE);
  237.   printText(0,MAX_DEVICES-1,buf);
  238.   delay(20*WAIT);
  239.   
  240.   // Time setting in RTC if Serial monitor is activated in Arduino IDE:
  241.   if (Serial.available() > 0 && timeset==false) {
  242.     adjustClock(Serial.readString());
  243.   }
  244. }
复制代码


回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 3 小时前

【Arduino 动手做】带 4x64 LED 矩阵的 Arduino Nano Clock

回复

使用道具 举报

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

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4 备案 沪公网安备31011502402448

© 2013-2025 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail