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 } } }
标签:动手做,dmd,String,Arduino,NORMAL,---,日期,drawString,GRAPHICS From: https://www.cnblogs.com/eagler8/p/17547287.html