本文要介紹的是一個(gè)由Arduino驅(qū)動(dòng)的數(shù)字時(shí)鐘,同時(shí)也是一個(gè)非常有趣的四沖程發(fā)動(dòng)機(jī)模擬器,通過小時(shí)和分鐘處的數(shù)字模擬汽車發(fā)動(dòng)機(jī)的活塞運(yùn)動(dòng)。
介紹
由Arduino驅(qū)動(dòng)的“四沖程數(shù)字時(shí)鐘”是一個(gè)有趣的數(shù)字時(shí)鐘內(nèi)燃機(jī)模擬器。小時(shí)和分鐘數(shù)字代表活塞移動(dòng)并具有精確的RPM控制(100到800),RPM由顯示屏中心的兩列顯示。
另一個(gè)有趣的視覺信息是氣缸的點(diǎn)火順序“1-3-4-2”。當(dāng)活塞在壓縮循環(huán)中位于氣缸頂部時(shí),火花開始。該項(xiàng)目可以作為學(xué)習(xí)管理點(diǎn)陣像素和引入簡單動(dòng)畫功能的一個(gè)很好的練習(xí)。
四沖程內(nèi)燃機(jī)
該項(xiàng)目中使用的發(fā)動(dòng)機(jī)型號(hào)是四沖程循環(huán)的I4(直列四缸)。四沖程內(nèi)燃機(jī)分為四個(gè)步驟(進(jìn)氣-壓縮-燃燒-排氣),其中一步如下圖所示:
注意:更多內(nèi)燃機(jī)的基本信息可以在維基百科上找到。
時(shí)鐘
在這個(gè)項(xiàng)目中,小時(shí)和分鐘的數(shù)字模擬了活塞的運(yùn)動(dòng),并且所有氣缸的火花在正確的時(shí)間突出顯示。
精確計(jì)算旋轉(zhuǎn)以表示實(shí)際速度,并通過旋轉(zhuǎn)電位計(jì)在100至800RPM(每分鐘轉(zhuǎn)數(shù))之間調(diào)整該值。
材料清單
ArduinoUNOR3
LED點(diǎn)陣與MAX7219
DS1307RTC(實(shí)時(shí)時(shí)鐘)
旋轉(zhuǎn)電位器-10KOhms
面包板
打印模板
跳線
3D打印文件:
示意圖:
本文所用到代碼:
#include // LED 矩陣庫 - MAX72XX
#include // DS1307RTC 庫 - Arduino UNO 的引腳:A4 (SDA), A5 (SCL)
#include // 實(shí)時(shí)時(shí)鐘庫
#include // 時(shí)間庫
#include
// 全局變量
字節(jié) hh, mm ; // 小時(shí),分鐘
字節(jié)uH,uM,dH,dM ; // 單位小時(shí),單位分鐘,青少年小時(shí),青少年分鐘
字節(jié)p = 0 ; // 繪圖模式(數(shù)字位置:上/下)
int RPM = 0 , lastRPM = 0 , pinRPM = 0 ; // RPM,RPM 的最后值,RPM 的模擬引腳
字節(jié)序列 = 1 ; // 開始火序列
/*
用于連接 MAX72XX的 Arduino 引腳號(hào)(帶 MAX72XX 控制器的 LED 陣列)
引腳5連接到 DataIn ( DIN )
引腳6連接到負(fù)載( CS )
引腳7連接到 CLK ( CLK )
*/
LedControl lc = LedControl ( 5 , 7 , 6 , 2 ) ; // LedControl ( int DIN, int CLK, int CS, int numDevices )
// 數(shù)字?jǐn)?shù)組 - ( 0到9 ) - 大小 5x3
字節(jié)數(shù)[ 10 ] [ 3 ] = {
{ 0xF8, 0x88, 0xF8 } , // 0
{ 0x00, 0xF8, 0x40 } , // 1
{ 0xE8, 0xA8, 0xB8 } , // 2
{ 0xF8, 0xA8, 0x88 } , // 3
{ 0x78, 0x20, 0xE0 } , // 4
{ 0xB8, 0xA8, 0xE8 } , // 5
{ 0xB8, 0xA8, 0xF8 } , // 6
{ 0xC0, 0xB8, 0x80 } , // 7
{ 0xF8, 0xA8, 0xF8 } , // 8
{ 0xF8, 0xA0, 0xE0 } , // 9
};
無效設(shè)置() {
setSyncProvider(RTC.get); // Function to read RTC (Real Time Clock)
setSyncInterval(60); // Set the number of seconds between re-sync
//setTime(8, 19, 30, 10, 02, 2018); // Set the Time and Date (hour, minute, second, day, month, year)
//RTC.set(now()); // Set the RTC time
// Setup of Display "0"
lc.shutdown(0, false); // Wakeup Display "0"
lc.setIntensity(0, 4); // Set the Brightness of Display (0 to 15)
lc.clearDisplay(0); // Clear Display "0"
// Setup of Display "1"
lc.shutdown(1, false); // Wakeup Display "1"
lc.setIntensity(1, 4); // Set the Brightness of Display (0 to 15)
lc.clearDisplay(1); // Clear Display "1"
}
void loop() {
hh = hour();
mm = minute();
uH = hh % 10;
dH = hh / 10;
uM = mm % 10;
dM = mm / 10;
// Plot Hours
for (byte k = 0; k < 3; k++) {
lc.setRow(0, k + 5, num[dH][k] >> (p + 2));
lc.setRow(0, k + 1, num[uH][k] >> (3 - p));
}
// Plot Minutes
for (byte k = 0; k < 3; k++) {
lc.setRow(1, k + 4, num[dM][k] >> (3 - p));
lc.setRow(1, k , num[uM][k] >> (p + 2));
}
// Plot Fire Sequence: 1-3-4-2 (4 cyl: 1-3-4-2 or 1-2-4-3 or 1-4-3-2)
if (seq == 1) { // Fire Cyl #1
lc.setLed(0, 6, 0, true);
}
if (seq == 2) { // Fire Cyl #3
lc.setLed(1, 5, 0, true);
}
if (seq == 3) { // Fire Cyl #4
lc.setLed(1, 1, 0, true);
}
if (seq == 4) { // Fire Cyl #2
lc.setLed(0, 2, 0, true);
}
seq = seq % 4 + 1;
// RPM reading
RPM = analogRead(pinRPM); // Potentiometer reading
RPM = map(RPM, 0, 1023, 1, 9);
if (RPM <= 8) {
lc.setLed(1, 7, 8 - RPM, true);
lc.setLed(0, 0, 8 - RPM, true);
delay(300 / RPM); // Speed setup by potentiometer (100 - 800 RPM)
if (lastRPM != RPM) {
lc.setRow(0, 0, 0);
lc.setRow ( 1 , 7 , 0 ) ;
最后轉(zhuǎn)數(shù) =轉(zhuǎn)數(shù);
}
}
p = !p ; // 切換數(shù)字位置(上 x 下)
}
-
模擬器
+關(guān)注
關(guān)注
2文章
879瀏覽量
43273 -
數(shù)字時(shí)鐘
+關(guān)注
關(guān)注
2文章
150瀏覽量
20389 -
Arduino
+關(guān)注
關(guān)注
188文章
6472瀏覽量
187330
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論