【雕爷学编程】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 } } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗