【雕爷学编程】Arduino动手做(117)---P10V706LED屏模组4

发布时间 2023-07-12 13:50:07作者: 行者花雕

37款传感器与执行器的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里准备逐一动手尝试系列实验,不管成功(程序走通)与否,都会记录下来—小小的进步或是搞不掂的问题,希望能够抛砖引玉。

 

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验一百一十七:P10单红V706模组 32*16单元板LED显示屏

 

 

程序十七:使用DS1307的大字时钟
(1)Arduino参考开源代码

/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  程序十七:使用DS1307的大字时钟
*/

//串口和RTC库
#include <Wire.h>
#include "RTClib.h"

//使用了 SPI、DMD、TimerOne 和 Font 库
#include <SPI.h>
#include <DMD.h>
#include <TimerOne.h>
#include "Arial_black_16.h"
#include "Font_6x14.h" //这个字体只包含 0-9 的数字。仅用于显示时间。

//配置P10
#define DISPLAYS_ACROSS 1 //使用的 P10 面板数量,左右。
#define DISPLAYS_DOWN 1
DMD dmd(DISPLAYS_ACROSS, DISPLAYS_DOWN);

RTC_DS1307 rtc; //RTC模块初始化

//时间和日期的变量
int _day, _month, _year, _hour24, _hour12, _minute, _second, _dtw;
int hr24;
String st;
char nameoftheday[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};//星期
char month_name[12][12] = {"January", "February", "March", "April", "May", "June", "Jult", "August", "September", "October", "November", "December"}; //月份

//Millis 的变量
const long interval = 1000; //每 1 秒检索一次时间和日期数据
unsigned long previousMillis = 0;

//显示小时和分钟的变量
char hr_24 [3];
String str_hr_24;
char mn [3];
String str_mn;

void ScanDMD() {
  dmd.scanDisplayBySPI();
}

void setup() {
  Serial.begin(115200);
  Serial.println("Arduino RTC DS1307");
  delay(1000);

  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    // 以下行将 RTC 设置为编译此草图的日期和时间(根据您的计算机时间和日期设置时间和日期)
    // rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); 
    //-> 根据您的计算机时间和日期设置时间和日期。如果这不起作用,请在“if (!rtc.isrunning())”之外使用这行代码
    // 此行使用明确的日期和时间设置 RTC,例如设置
    // 2022 年 5 月 21 日凌晨 6 点,您可以设置:
    rtc.adjust(DateTime(2022, 5, 21, 6, 0, 0));
  }
  // 以下行将 RTC 设置为编译此草图的日期和时间(根据您的计算机时间和日期设置时间和日期)
  // rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); 
  //-> 根据您的计算机时间和日期设置时间和日期。如果在“if (!rtc.isrunning())”中不起作用,请使用这行代码
  // rtc.adjust(DateTime(2022, 5, 21, 6, 0, 0));
  // 如果时间和日期设置成功,则停用代码行(使代码成为注释),然后重新上传代码。
  // 如果没有完成,那么时间和日期将返回到 arduino 重置或重新启动时设置的开头。

  Timer1.initialize(1000);
  Timer1.attachInterrupt(ScanDMD);
  dmd.clearScreen(true);
}

void loop() {
  //millis() 显示时间
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis; //保存最后一次

    GetDateTime(); //从 DS1307 检索时间和日期数据

    dmd.selectFont(Font_6x14);

    //在 P10 中显示小时
    str_hr_24 = String(_hour24);
    str_hr_24.toCharArray(hr_24, 3);

    if (_hour24 < 10) {
      dmd.drawString(0, 0, "0", 1, GRAPHICS_NORMAL);
      dmd.drawString(7, 0, hr_24, 1, GRAPHICS_NORMAL);
    }
    else {
      dmd.drawString(0, 0, hr_24, 2, GRAPHICS_NORMAL);
    }
   
    //在 P10 中显示“:”
    if (_second % 2 == 0) {
      dmd.drawFilledBox(15, 3, 16, 4, GRAPHICS_OR);
      dmd.drawFilledBox(15, 11, 16, 12, GRAPHICS_OR);
    }
    else {
      dmd.drawFilledBox(15, 3, 16, 4, GRAPHICS_NOR);
      dmd.drawFilledBox(15, 11, 16, 12, GRAPHICS_NOR);
    }
    
    //在 P10 中显示分钟
    str_mn = String(_minute);
    str_mn.toCharArray(mn, 3);

    if (_minute < 10) {
      dmd.drawString(19, 0, "0", 1, GRAPHICS_NORMAL);
      dmd.drawString(26, 0, mn, 1, GRAPHICS_NORMAL);
    }
    else {
      dmd.drawString(19, 0, mn, 2, GRAPHICS_NORMAL);
    }
    
    //调用 scrolling_date() 子例程来显示日期。
    if (_second == 11) { //当秒数等于 11 时显示日期
      scrolling_date();
    }
  }
}

//从 DS1307 检索或更新时间和日期的子程序
void GetDateTime() {
  DateTime now = rtc.now();
  _day = now.day();
  _month = now.month();
  _year = now.year();
  _hour24 = now.hour();
  _minute = now.minute();
  _second = now.second();
  _dtw = now.dayOfTheWeek();

  hr24 = _hour24;
  if (hr24 > 12) {
    _hour12 = hr24 - 12;
  }
  else if (hr24 == 0) {
    _hour12 = 12;
  }
  else {
    _hour12 = hr24;
  }

  if (hr24 < 12) {
    st = "AM";
  }
  else {
    st = "PM";
  }
}

//显示日、月、年的子程序
void scrolling_date() {
  String Date = String(nameoftheday[_dtw]) + ", " + String(_day) + "-" + String(month_name[_month - 1]) + "-" + String(_year);
  char dt[50];
  Date.toCharArray(dt, 50);

  dmd.clearScreen(true);
  dmd.selectFont(Arial_Black_16);
  dmd.drawMarquee(dt, strlen(dt), (32 * DISPLAYS_ACROSS) - 1, 0);
  boolean ret = false;
  while (!ret) {
    ret = dmd.stepMarquee(-1, 0);
    delay(75); //延迟滚动速度
  }
  dmd.clearScreen(true);
  return;
}

  

(2)实验接线示意图

(3)实验场景图

 

程序十八:使用DS1307的双行字日期时钟
(1)Arduino参考开源代码

/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  程序十八:使用DS1307的双行字日期时钟
*/

//RTC库
#include "RTClib.h"

//使用了 SPI、DMD、TimerOne 和 Font 库
#include <SPI.h>
#include <DMD.h>
#include <TimerOne.h>
#include "SystemFont5x7.h"
#include "Font_6x14.h" //这个字体只包含 0-9 的数字。仅用于显示时间。

//配置P10
#define DISPLAYS_ACROSS 1 //使用的 P10 面板数量,左右。
#define DISPLAYS_DOWN 1
DMD dmd(DISPLAYS_ACROSS, DISPLAYS_DOWN);


RTC_DS1307 rtc; //RTC模块初始化

//时间和日期的变量
int _day, _month, _year, _hour24, _hour12, _minute, _second, _dtw;
int hr24;
String st;
char nameoftheday[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
char month_name[12][12] = {"January", "February", "March", "April", "May", "June", "Jult", "August", "September", "October", "November", "December"};

//Millis 的变量
const long interval = 1000; //每 1 秒检索一次时间和日期数据
unsigned long previousMillis = 0;

const long interval_for_date = 75; //滚动速度
unsigned long previousMillis_for_date = 0;

//显示小时和分钟的变量
char hr_24 [3];
String str_hr_24;
char mn [3];
String str_mn;

void ScanDMD() {
  dmd.scanDisplayBySPI();
}

void setup() {
  Serial.begin(115200);
  Serial.println("Arduino RTC DS1307准备就绪");
  delay(1000);

  if (! rtc.begin()) {
    Serial.println("找不到 RTC");
    while (1);
  }

  if (! rtc.isrunning()) {
    Serial.println("RTC 没有运行!");
    // 以下行将 RTC 设置为编译此草图的日期和时间(根据您的计算机时间和日期设置时间和日期)
    // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    //-> 根据您的计算机时间和日期设置时间和日期。如果这不起作用,请在“if (!rtc.isrunning())”之外使用这行代码
    // 此行使用明确的日期和时间设置 RTC,例如设置
    // 2022 年 5 月 21 日凌晨 6 点,您可以设置:
    rtc.adjust(DateTime(2022, 5, 21, 6, 0, 0));
  }
  // 以下行将 RTC 设置为编译此草图的日期和时间(根据您的计算机时间和日期设置时间和日期)
  // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  //-> 根据您的计算机时间和日期设置时间和日期。如果在“if (!rtc.isrunning())”中不起作用,请使用这行代码
  // rtc.adjust(DateTime(2022, 5, 21, 6, 0, 0));
  // 如果时间和日期设置成功,则停用代码行(使代码成为注释),然后重新上传代码。
  // 如果没有完成,那么时间和日期将返回到 arduino 重置或重新启动时设置的开头。

  Timer1.initialize(1000);
  Timer1.attachInterrupt(ScanDMD);
  dmd.clearScreen(true);
}

void loop() {
  //millis() 显示时间
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis; //保存最后一次

    GetDateTime(); //从 DS1307 检索时间和日期数据

    dmd.selectFont(Font_6x14);

    //在 P10 中显示小时
    str_hr_24 = String(_hour24);
    str_hr_24.toCharArray(hr_24, 3);

    if (_hour24 < 10) {
      dmd.drawString(0, 0, "0", 1, GRAPHICS_NORMAL);
      dmd.drawString(7, 0, hr_24, 1, GRAPHICS_NORMAL);
    }
    else {
      dmd.drawString(0, 0, hr_24, 2, GRAPHICS_NORMAL);
    }

    //在 P10 中显示“:”
    if (_second % 2 == 0) {
      dmd.drawFilledBox(15, 3, 16, 4, GRAPHICS_OR);
      dmd.drawFilledBox(15, 11, 16, 12, GRAPHICS_OR);
    }
    else {
      dmd.drawFilledBox(15, 3, 16, 4, GRAPHICS_NOR);
      dmd.drawFilledBox(15, 11, 16, 12, GRAPHICS_NOR);
    }

    //在 P10 中显示分钟
    str_mn = String(_minute);
    str_mn.toCharArray(mn, 3);

    if (_minute < 10) {
      dmd.drawString(19, 0, "0", 1, GRAPHICS_NORMAL);
      dmd.drawString(26, 0, mn, 1, GRAPHICS_NORMAL);
    }
    else {
      dmd.drawString(19, 0, mn, 2, GRAPHICS_NORMAL);
    }

    //调用 scrolling_date() 子例程来显示日期。
    if (_second == 11) { //当秒数等于 11 时显示日期
      scrolling_date();
    }
  }
}

//从 DS1307 检索或更新时间和日期的子程序
void GetDateTime() {
  DateTime now = rtc.now();
  _day = now.day();
  _month = now.month();
  _year = now.year();
  _hour24 = now.hour();
  _minute = now.minute();
  _second = now.second();
  _dtw = now.dayOfTheWeek();

  hr24 = _hour24;
  if (hr24 > 12) {
    _hour12 = hr24 - 12;
  }
  else if (hr24 == 0) {
    _hour12 = 12;
  }
  else {
    _hour12 = hr24;
  }

  if (hr24 < 12) {
    st = "AM";
  }
  else {
    st = "PM";
  }
}

//显示日、月、年的子程序
void scrolling_date() {
  dmd.clearScreen(true);
  delay(100);

  //保存要显示的日期数据
  String Date = String(nameoftheday[_dtw]) + ", " + String(_day) + "-" + String(month_name[_month - 1]) + "-" + String(_year);
  char dt[50];
  Date.toCharArray(dt, 50);
  int i = 32 + 10;
  int j = strlen(dt) + (strlen(dt) * 5);

  dmd.selectFont(SystemFont5x7);

  while (1) {
    //millis() 显示时间
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis; //保存最后一次

      //在 P10 中显示时钟
      str_hr_24 = String(_hour24);
      str_hr_24.toCharArray(hr_24, 3);

      if (_hour24 < 10) {
        dmd.drawString(2, 0, "0", 1, GRAPHICS_NORMAL);
        dmd.drawString(8, 0, hr_24, 1, GRAPHICS_NORMAL);
      }
      else {
        dmd.drawString(2, 0, hr_24, 2, GRAPHICS_NORMAL);
      }

      //在 P10 中显示“:”
      GetDateTime(); // 从 DS1307 检索时间和日期数据
      if (_second % 2 == 0) {
        dmd.drawString(14, 0, ":", 2, GRAPHICS_OR);
      }
      else {
        dmd.drawString(14, 0, ":", 2, GRAPHICS_NOR);
      }

      //在 P10 中显示分钟
      str_mn = String(_minute);
      str_mn.toCharArray(mn, 3);

      if (_minute < 10) {
        dmd.drawString(19, 0, "0", 1, GRAPHICS_NORMAL);
        dmd.drawString(25, 0, mn, 1, GRAPHICS_NORMAL);
      }
      else {
        dmd.drawString(19, 0, mn, 2, GRAPHICS_NORMAL);
      }
    }

    //millis() 用于显示和滚动日期
    unsigned long currentMillis_for_date = millis();
    if (currentMillis_for_date - previousMillis_for_date >= interval_for_date) {
      previousMillis_for_date = currentMillis_for_date; //保存最后一次时间

      i--;
      dmd.drawString(i, 9, dt, strlen(dt), GRAPHICS_NORMAL);
      if (i <= ~j) {
        dmd.clearScreen(true);
        delay(100);
        return;
      }
    }
  }
}

  

(2)实验场景图

程序十九:显示时、分、秒和日期的时钟
(1)Arduino参考开源代码

/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  程序十九:显示时、分、秒和日期的时钟
*/

//RTC库
#include <Wire.h>
#include "RTClib.h"

//使用了 SPI、DMD、TimerOne 和 Font 库
#include <SPI.h>
#include <DMD.h>
#include <TimerOne.h>
#include "SystemFont5x7.h"
#include "Font_6x14.h" //这个字体只包含 0-9 的数字。仅用于显示时间。

//配置P10
#define DISPLAYS_ACROSS 1 //使用的 P10 面板数量,左右。
#define DISPLAYS_DOWN 1
DMD dmd(DISPLAYS_ACROSS, DISPLAYS_DOWN);


RTC_DS1307 rtc; //RTC模块初始化

//时间和日期的变量
int _day, _month, _year, _hour24, _hour12, _minute, _second, _dtw;
int hr24;
String st;
char nameoftheday[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
char month_name[12][12] = {"January", "February", "March", "April", "May", "June", "Jult", "August", "September", "October", "November", "December"};

//Millis 的变量
const long interval = 1000; //每 1 秒检索一次时间和日期数据
unsigned long previousMillis = 0;

const long interval_for_date = 75; //滚动速度
unsigned long previousMillis_for_date = 0;

//显示小时\分钟\秒的变量
char hr_24 [3];
String str_hr_24;
char mn [3];
String str_mn;
char sc [3];
String str_sc;

void ScanDMD() {
  dmd.scanDisplayBySPI();
}

void setup() {
  Serial.begin(115200);
  Serial.println("Arduino RTC DS1307准备就绪");
  delay(1000);

  if (! rtc.begin()) {
    Serial.println("找不到 RTC");
    while (1);
  }

  if (! rtc.isrunning()) {
    Serial.println("RTC 没有运行!");
    // 以下行将 RTC 设置为编译此草图的日期和时间(根据您的计算机时间和日期设置时间和日期)
    // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // 根据您的计算机时间和日期设置时间和日期。如果这不起作用,请在“if (!rtc.isrunning())”之外使用这行代码
    // 此行使用明确的日期和时间设置 RTC,例如设置
    // 2022 年 5 月 21 日凌晨 6 点,您可以设置:
    rtc.adjust(DateTime(2022, 5, 21, 6, 0, 0));
  }
  // 以下行将 RTC 设置为编译此草图的日期和时间(根据您的计算机时间和日期设置时间和日期)
  // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  // 根据您的计算机时间和日期设置时间和日期。如果在“if (!rtc.isrunning())”中不起作用,请使用这行代码
  // rtc.adjust(DateTime(2022, 5, 21, 6, 0, 0));
  // 如果时间和日期设置成功,则停用代码行(使代码成为注释),然后重新上传代码。
  // 如果没有完成,那么时间和日期将返回到 arduino 重置或重新启动时设置的开头。

  Timer1.initialize(1000);
  Timer1.attachInterrupt(ScanDMD);
  dmd.clearScreen(true);
}

void loop() {
  //millis() 显示时间
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis; //保存最后一次

    GetDateTime(); //从 DS1307 检索时间和日期数据

    dmd.selectFont(Font_6x14);

    //在 P10 中显示小时
    str_hr_24 = String(_hour24);
    str_hr_24.toCharArray(hr_24, 3);

    if (_hour24 < 10) {
      dmd.drawString(1, 0, "0", 1, GRAPHICS_NORMAL);
      dmd.drawString(8, 0, hr_24, 1, GRAPHICS_NORMAL);
    }
    else {
      dmd.drawString(1, 0, hr_24, 2, GRAPHICS_NORMAL);
    }

    //在 P10 中显示“:”
    dmd.drawFilledBox(16, 3, 17, 4, GRAPHICS_NORMAL);
    dmd.drawFilledBox(16, 11, 17, 12, GRAPHICS_NORMAL);

    //在 P10 中显示分和秒
    dmd.selectFont(SystemFont5x7);
    str_mn = String(_minute);
    str_mn.toCharArray(mn, 3);

    if (_minute < 10) {
      dmd.drawString(20, 0, "0", 1, GRAPHICS_NORMAL);
      dmd.drawString(26, 0, mn, 1, GRAPHICS_NORMAL);
    }
    else {
      dmd.drawString(20, 0, mn, 2, GRAPHICS_NORMAL);
    }

    str_sc = String(_second);
    str_sc.toCharArray(sc, 3);

    if (_second < 10) {
      dmd.drawString(20, 9, "0", 1, GRAPHICS_NORMAL);
      dmd.drawString(26, 9, sc, 1, GRAPHICS_NORMAL);
    }
    else {
      dmd.drawString(20, 9, sc, 2, GRAPHICS_NORMAL);
    }

    //调用 scrolling_date() 子例程来显示日期。
    if (_second == 11) { //秒等于 11 时显示日期
      scrolling_date();
    }
  }
}

//从 DS1307 检索或更新时间和日期的子程序
void GetDateTime() {
  DateTime now = rtc.now();
  _day = now.day();
  _month = now.month();
  _year = now.year();
  _hour24 = now.hour();
  _minute = now.minute();
  _second = now.second();
  _dtw = now.dayOfTheWeek();

  hr24 = _hour24;
  if (hr24 > 12) {
    _hour12 = hr24 - 12;
  }
  else if (hr24 == 0) {
    _hour12 = 12;
  }
  else {
    _hour12 = hr24;
  }

  if (hr24 < 12) {
    st = "AM";
  }
  else {
    st = "PM";
  }
}

//显示日、月、年的子程序
void scrolling_date() {
  dmd.clearScreen(true);
  delay(100);

  //保存要显示的日期数据
  String Date = String(nameoftheday[_dtw]) + ", " + String(_day) + "-" + String(month_name[_month - 1]) + "-" + String(_year);
  char dt[50];
  Date.toCharArray(dt, 50);
  int i = 32 + 10;
  int j = strlen(dt) + (strlen(dt) * 5);

  dmd.selectFont(SystemFont5x7);

  while (1) {
    //millis() 显示时间
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis; //保存最后一次时间

      //在 P10 中显示时钟
      str_hr_24 = String(_hour24);
      str_hr_24.toCharArray(hr_24, 3);

      if (_hour24 < 10) {
        dmd.drawString(2, 0, "0", 1, GRAPHICS_NORMAL);
        dmd.drawString(8, 0, hr_24, 1, GRAPHICS_NORMAL);
      }
      else {
        dmd.drawString(2, 0, hr_24, 2, GRAPHICS_NORMAL);
      }

      //在 P10 中显示“:”
      GetDateTime(); //从 DS1307 检索时间和日期数据
      if (_second % 2 == 0) {
        dmd.drawString(14, 0, ":", 2, GRAPHICS_OR);
      }
      else {
        dmd.drawString(14, 0, ":", 2, GRAPHICS_NOR);
      }

      //在 P10 中显示分钟
      str_mn = String(_minute);
      str_mn.toCharArray(mn, 3);

      if (_minute < 10) {
        dmd.drawString(19, 0, "0", 1, GRAPHICS_NORMAL);
        dmd.drawString(25, 0, mn, 1, GRAPHICS_NORMAL);
      }
      else {
        dmd.drawString(19, 0, mn, 2, GRAPHICS_NORMAL);
      }
    }

    //millis() 用于显示和滚动日期
    unsigned long currentMillis_for_date = millis();
    if (currentMillis_for_date - previousMillis_for_date >= interval_for_date) {
      previousMillis_for_date = currentMillis_for_date; //保存最后一次时间

      i--;
      dmd.drawString(i, 9, dt, strlen(dt), GRAPHICS_NORMAL);
      if (i <= ~j) {
        dmd.clearScreen(true);
        delay(100);
        return;
      }
    }
  }
}

  

(2)实验场景图

程序二十:P10显示屏数码时钟(风格之四)
(1)Arduino参考开源代码

/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  程序二十:P10显示屏数码时钟(风格之四)
*/

//RTC库
#include <Wire.h>
#include "RTClib.h"

//使用了 SPI、DMD、TimerOne 和 Font 库
#include <SPI.h>
#include <DMD.h>
#include <TimerOne.h>
#include "SystemFont5x7.h"

//配置P10
#define DISPLAYS_ACROSS 1 //使用的 P10 面板数量,左右。
#define DISPLAYS_DOWN 1
DMD dmd(DISPLAYS_ACROSS, DISPLAYS_DOWN);


RTC_DS1307 rtc; //RTC模块初始化

//时间和日期的变量
int _day, _month, _year, _hour24, _hour12, _minute, _second, _dtw;
int hr24;
String st;
char nameoftheday[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
char month_name[12][12] = {"January", "February", "March", "April", "May", "June", "Jult", "August", "September", "October", "November", "December"};

//Millis 的变量
const long interval = 1000; //每 1 秒检索一次时间和日期数据
unsigned long previousMillis = 0;

const long interval_for_date = 75; //滚动速度
unsigned long previousMillis_for_date = 0;

//显示小时\分钟\秒的变量
char hr_24 [3];
String str_hr_24;
char mn [3];
String str_mn;
char sc [3];
String str_sc;

String strSecondRow;
char chrSecondRow[60];
int i = 32;
int j;
int sr = 1;

void ScanDMD() {
  dmd.scanDisplayBySPI();
}

void setup() {
  Serial.begin(115200);
  Serial.println("Arduino RTC DS1307准备就绪");
  delay(1000);

  if (! rtc.begin()) {
    Serial.println("找不到 RTC");
    while (1);
  }

  if (! rtc.isrunning()) {
    Serial.println("RTC 没有运行!");
    // 以下行将 RTC 设置为编译此草图的日期和时间(根据您的计算机时间和日期设置时间和日期)
    // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // 根据您的计算机时间和日期设置时间和日期。如果这不起作用,请在“if (!rtc.isrunning())”之外使用这行代码
    // 此行使用明确的日期和时间设置 RTC,例如设置
    // 2022 年 5 月 21 日凌晨 6 点,您可以设置:
    rtc.adjust(DateTime(2022, 5, 21, 6, 0, 0));
  }
  // 以下行将 RTC 设置为编译此草图的日期和时间(根据您的计算机时间和日期设置时间和日期)
  // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  // 根据您的计算机时间和日期设置时间和日期。如果在“if (!rtc.isrunning())”中不起作用,请使用这行代码
  // rtc.adjust(DateTime(2022, 5, 21, 6, 0, 0));
  // 如果时间和日期设置成功,则停用代码行(使代码成为注释),然后重新上传代码。
  // 如果没有完成,那么时间和日期将返回到 arduino 重置或重新启动时设置的开头。

  Timer1.initialize(1000);
  Timer1.attachInterrupt(ScanDMD);
  dmd.clearScreen(true);
  dmd.selectFont(SystemFont5x7);
}

void loop() {
  //millis() 显示时间
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis; //保存最后一次

    GetDateTime(); //从 DS1307 检索时间和日期数据

    //在 P10 中显示小时
    str_hr_24 = String(_hour24);
    str_hr_24.toCharArray(hr_24, 3);

    if (_hour24 < 10) {
      dmd.drawString(2, 0, "0", 1, GRAPHICS_NORMAL);
      dmd.drawString(8, 0, hr_24, 1, GRAPHICS_NORMAL);
    }
    else {
      dmd.drawString(2, 0, hr_24, 2, GRAPHICS_NORMAL);
    }

    //在 P10 中显示“:”
    GetDateTime(); //从 DS1307 检索时间和日期数据
    if (_second % 2 == 0) {
      dmd.drawString(14, 0, ":", 2, GRAPHICS_OR);
    }
    else {
      dmd.drawString(14, 0, ":", 2, GRAPHICS_NOR);
    }

    //在 P10 中显示分和秒
    str_mn = String(_minute);
    str_mn.toCharArray(mn, 3);

    if (_minute < 10) {
      dmd.drawString(19, 0, "0", 1, GRAPHICS_NORMAL);
      dmd.drawString(25, 0, mn, 1, GRAPHICS_NORMAL);
    }
    else {
      dmd.drawString(19, 0, mn, 2, GRAPHICS_NORMAL);
    }
  }

  //millis() 用于显示/滚动日期和其他文本
  unsigned long currentMillis_for_date = millis();
  if (currentMillis_for_date - previousMillis_for_date >= interval_for_date) {
    previousMillis_for_date = currentMillis_for_date; //保存最后一次时间

    //保存日期数据和其他要显示的文本
    switch (sr) {
      case 1:
        strSecondRow = String(nameoftheday[_dtw]) + ", " + String(_day) + "-" + String(month_name[_month - 1]) + "-" + String(_year);
        strSecondRow.toCharArray(chrSecondRow, 60);
        j = strlen(chrSecondRow) + (strlen(chrSecondRow) * 5);
        break;
      case 2:
        strSecondRow = "Don't Forget to Subscribe Uteh Str Channel on YouTube";
        strSecondRow.toCharArray(chrSecondRow, 60);
        j = strlen(chrSecondRow) + (strlen(chrSecondRow) * 5);
        break;
    }

    i--;
    dmd.drawString(i, 9, chrSecondRow, strlen(chrSecondRow), GRAPHICS_NORMAL);
    if (i <= ~j) {
      i = 32;
      sr++;
      if (sr > 2) sr = 1;
    }
  }
}

//从 DS1307 检索或更新时间和日期的子程序
void GetDateTime() {
  DateTime now = rtc.now();
  _day = now.day();
  _month = now.month();
  _year = now.year();
  _hour24 = now.hour();
  _minute = now.minute();
  _second = now.second();
  _dtw = now.dayOfTheWeek();

  hr24 = _hour24;
  if (hr24 > 12) {
    _hour12 = hr24 - 12;
  }
  else if (hr24 == 0) {
    _hour12 = 12;
  }
  else {
    _hour12 = hr24;
  }

  if (hr24 < 12) {
    st = "AM";
  }
  else {
    st = "PM";
  }
}

  

(2)实验场景图

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验一百一十七:P10单红V706模组 32*16单元板LED显示屏
项目程序二十一:显示字符显示无误且长度合适

 

/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验一百二十三: P10单红V706模组  32*16单元板LED显示屏
  项目程序二十一:显示字符显示无误且长度合适
*/

#include <SPI.h>
#include <DMD.h>
#include <TimerOne.h>
#include "SystemFont5x7.h"
#include "Arial_black_16.h"
#include "Arial14.h"
#define DISPLAYS_ACROSS 1
#define DISPLAYS_DOWN 1
String str;
char b[8];
DMD dmd(DISPLAYS_ACROSS, DISPLAYS_DOWN);

void ScanDMD(){
dmd.scanDisplayBySPI();
}

void setup() {
Serial.begin(9600);
Timer1.initialize(5000);
Timer1.attachInterrupt(ScanDMD);
dmd.clearScreen(true);
}

void loop()
{
int slen = 0;
dmd.clearScreen( true );                             
/*---------------------------------------  Display using SystemFont  -------------------------------------*/
dmd.selectFont(SystemFont5x7);                                 
str="HELLO";
slen = str.length()+1;    
str.toCharArray(b,slen);   
dmd.drawString(1,0,b,slen,GRAPHICS_NORMAL);                                        
str="WORLD";   
slen= str.length()+1;                                          
str.toCharArray(b,slen);         
dmd.drawString(1,8,b,slen,GRAPHICS_NORMAL);      
delay(4000);                   
dmd.clearScreen( true );
delay(2000);  

/*---------------------------------  Display using Arial_black_16  -------------------------------------*/
dmd.selectFont(Arial_Black_16);                
str="BEP";                                           
slen = str.length()+1;                                       
str.toCharArray(b,slen);       
dmd.drawString(2,1,b,slen,GRAPHICS_NORMAL);      
delay(4000);   
dmd.clearScreen( true );
delay(2000);                     

/*----------------------------------  Display using  Arial14  -------------------------------------------- */   
dmd.selectFont(Arial_14);                                      
str="BEP!";                                          
slen = str.length()+1;                                       
str.toCharArray(b,slen);       
dmd.drawString(4,1,b,slen,GRAPHICS_NORMAL);        
delay(4000);
dmd.clearScreen( true );
delay(2000);                           
}

  

实验场景图

 

#define LIN_OUT 1
#define FHT_N 128 // set to 256 point fht 128

#include <FHT.h> // include the library
#include <SPI.h>
#include <DMD.h>        //
#include <TimerOne.h>   //
#include "SystemFont5x7.h"
#include "Arial_black_16.h"

#define DISPLAYS_ACROSS 1
#define DISPLAYS_DOWN 1
DMD dmd(DISPLAYS_ACROSS, DISPLAYS_DOWN);

//-------------------------------------------------------------------------------
// Change this to MONO to for a one-channel full-display or STEREO for two-channel
//
String displayType = "MONO";
//
// Change this to MONO to for a one-channel full-display or STEREO for two-channel
//-------------------------------------------------------------------------------

byte sampleR[64]; //64
byte sampleL[64];
unsigned long startTime, endTime, oldTime;
String displayText = "DY";
String sampleSet;
int displaySize;

void ScanDMD()
{ 
  dmd.scanDisplayBySPI();
}

void setup() {

  if (displayType == "MONO") {displaySize = 32;} else {displaySize = 16;}
  
  //TIMSK0 = 0; // turn off timer0 for lower jitter
  ADCSRA = 0xe7; // set the adc to free running mode
  ADMUX = 0x45; // use adc5
  DIDR0 = 0x20; // turn off the digital input for adc5

  Timer1.initialize( 5000 );           //period in microseconds to call ScanDMD. Anything longer than 5000 (5ms) and you can see flicker.
  Timer1.attachInterrupt( ScanDMD );   //attach the Timer1 interrupt to ScanDMD which goes to dmd.scanDisplayBySPI()
  dmd.clearScreen( true );   //true is normal (all pixels off), false is negative (all pixels on)

  dmd.selectFont(Arial_Black_16); // show off who wrote the app... :p
  dmd.drawString(6,1,"DY",2,GRAPHICS_NORMAL);
  delay(3000);
  dmd.drawString(6,1,"CJ",2,GRAPHICS_NORMAL);
  delay(3000);
  dmd.selectFont(SystemFont5x7);
  dmd.drawString(2,0,"Audio",5,GRAPHICS_NORMAL);
  dmd.drawString(2,9,"Analy",5,GRAPHICS_NORMAL);
  delay(3000);

}

void loop() {

  startTime = millis();
  sampleSet = "L";
  sampleInput();
  sampleFix();
  if (displaySize == 16) {
    sampleSet = "R";
    sampleInput();
    sampleFix();
  }
  drawSpectrum();
  endTime = millis();
}

void drawSpectrum () {

  if (displaySize == 16) {
    dmd.clearScreen(true);
    for (int disX; disX < 16; disX++) {
      dmd.drawLine (disX, 16, disX, 16-sampleL[disX+1], GRAPHICS_NORMAL );
      dmd.drawLine (17+disX, 16, 17+disX, 16-sampleR[disX+1], GRAPHICS_NORMAL );
    }
  } 
  else {
    dmd.clearScreen(true);
    for (int disX; disX < 33; disX++) {
      dmd.drawLine (disX, 16, disX, 16-sampleL[disX+1], GRAPHICS_NORMAL );
    }
  }
}

void sampleInput() {
  cli();  // UDRE interrupt slows this way down on arduino1.0
  for (int x=0; x<FHT_N; x++) {
    while(!(ADCSRA & 0x10)); // wait for adc to be ready
    ADCSRA = 0xf5; // restart adc
    if (sampleSet == "L") {
      ADMUX = 0x45; // use adc5
    } else {
      ADMUX = 0x44; // use adc4
    }
    byte m = ADCL; // fetch adc data
    byte j = ADCH;
    int k = (j << 8) | m; // form into an int 8
    k -= 0x0200; // form into a signed int
    k <<= 6; // form into a 16b signed int 6
    fht_input[x] = k; // put real data into bins
  }
  sei();
  fht_window(); // window the data for better frequency response
  fht_reorder(); // reorder the data before doing the fht
  fht_run(); // process the data in the fht
  fht_mag_lin();

}

void sampleFix() {

  int newPos; 
  float fhtCount, tempY;
  for (int x=0; x < displaySize; x++) {
    fhtCount = FHT_N/2;  // 2
    newPos = x * (fhtCount / displaySize); // single channel half-display 15-LED wide
    tempY = fht_lin_out[newPos]; 
    if (sampleSet == "L") {
    sampleL[x] = ((tempY/256)*16); // single channel full 16 LED high
    } else {
    sampleR[x] = ((tempY/256)*16); // single channel full 16 LED high
    }
  }  
}