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

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

 

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

 

 

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/*
  【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参考开源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
/*
  【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参考开源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
/*
  【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参考开源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/*
  【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显示屏
项目程序二十一:显示字符显示无误且长度合适

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
/*
  【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);                          
}

  

实验场景图

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#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
    }
  
}

  

 

posted @   行者花雕  阅读(47)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗
点击右上角即可分享
微信分享提示