資料介紹
描述
#25projectsofchristmas
數(shù)字物聯(lián)網(wǎng)作弊骰子
M5STickC-plus 具有內(nèi)置加速度計(jì)。和一個(gè)顯示器。有了這個(gè),您可以輕松地對(duì)數(shù)字骰子進(jìn)行編程,當(dāng)您搖動(dòng)設(shè)備時(shí)會(huì)產(chǎn)生新的值。此外,M5STickC-plus 還擁有一個(gè) WiFi 芯片,可以讓它連接到互聯(lián)網(wǎng)。這就是物聯(lián)網(wǎng)進(jìn)入游戲的地方:想象一下和你的朋友玩骰子,看看誰(shuí)在酒吧買單。估計(jì)最遠(yuǎn)的人必須支付。您搖動(dòng) M5Stick 并將其正面朝下放在桌子上。每個(gè)人都必須猜測(cè)一個(gè)值,但您首先檢查您的智能手機(jī)以查看滾動(dòng)的值,因?yàn)槟腻X包中沒(méi)有足夠的錢來(lái)支付賬單。
骰子展示
兩個(gè)骰子的值應(yīng)該顯示在顯示器上,骰子應(yīng)該看起來(lái)像骰子:
為此,首先將沒(méi)有點(diǎn)的骰子圖像加載為背景圖像。
現(xiàn)在,根據(jù)隨機(jī)生成的 1 到 6 之間的值,必須在骰子的區(qū)域上繪制點(diǎn)。為此,6 個(gè)可能值的點(diǎn)坐標(biāo)存儲(chǔ)在一個(gè) 3 維數(shù)組中:
// Array to define the position of the dots on the dice
int dot_positions[7][6][2] {
{}, // 0
{{55,55}}, // 1
{{25,25},{85,85}}, // 2
{{25,25},{55,55},{85,85}}, // 3
{{25,25},{85,25},{25,85},{85,85}}, // 4
{{25,25},{85,25},{55,55},{25,85},{85,85}},// 5
{{25,25},{25,55},{25,85},{85,25},{85,55},{85,85}}, // 6
};
我認(rèn)為這些值需要解釋得更詳細(xì)一點(diǎn):M5StickC-plus 的顯示器分辨率為135*240 像素。空間足以容納兩個(gè)大小為 110x110 像素的芯片圖像。原點(diǎn)在左上角,模具上每個(gè)可能的點(diǎn)位置的坐標(biāo)可以這樣定義:
如果現(xiàn)在擲出 2,則必須在顯示屏上的相應(yīng)位置繪制兩個(gè)圓圈。為了讓骰子的點(diǎn)位于正確的位置,坐標(biāo)必須在顯示器上移動(dòng)骰子的目標(biāo)位置:
dot_positions []數(shù)組包含骰子可以取的所有 6 個(gè)值對(duì)應(yīng)的圓的位置。然后可以使用它來(lái)編寫(xiě)一個(gè)簡(jiǎn)單的函數(shù),為 1 到 6 之間的每個(gè)數(shù)值繪制相應(yīng)的點(diǎn)排列:
// function to draw the dice
void draw_dice(int16_t x, int16_t y, int dice_value) {
// M5StickC-plus Display size is 135x240
// Dice size is 110x110
M5.Lcd.pushImage(x, y, 110, 110, (uint16_t *)Dice_background);
if(dice_value > 0 && dice_value < 7){
for(int dot_index = 0; dot_index < dice_value; dot_index++) {
M5.Lcd.fillCircle(x+dot_positions[dice_value][dot_index][0],
y+dot_positions[dice_value][dot_index][1],
DOT_SIZE, TFT_BLACK);
}
}
}
如上所述,對(duì)值為 2 的骰子的函數(shù)調(diào)用將如下所示:
draw_dice(12,9, 2);
現(xiàn)在我們可以畫(huà)骰子了,但是應(yīng)用程序仍然需要在一個(gè)好的過(guò)程中運(yùn)行。所以我們需要一個(gè)“過(guò)程序列控制東西功能的東西” ,或者換句話說(shuō):我們需要一個(gè)狀態(tài)機(jī)!
有限狀態(tài)機(jī)
所謂的“狀態(tài)機(jī)”是過(guò)程序列的行為模型。它由有限數(shù)量的狀態(tài)組成,因此通常稱為有限狀態(tài)機(jī) (FSM)。簡(jiǎn)單地說(shuō):基于當(dāng)前狀態(tài)和給定輸入,狀態(tài)機(jī)執(zhí)行狀態(tài)轉(zhuǎn)換并產(chǎn)生輸出。這聽(tīng)起來(lái)比實(shí)際更復(fù)雜。對(duì)于骰子軟件,我們可以定義三個(gè)簡(jiǎn)單的狀態(tài):
軟件應(yīng)保持在啟動(dòng)狀態(tài),直到檢測(cè)到設(shè)備晃動(dòng)。然后結(jié)果應(yīng)該只在搖動(dòng)停止時(shí)顯示。因此,軟件應(yīng)保持在搖動(dòng)狀態(tài),直到檢測(cè)到搖動(dòng)結(jié)束。最后,軟件應(yīng)保持顯示狀態(tài),直到按下 M5Stick 上的按鈕。這是狀態(tài)機(jī)的基本原理。
為了表示骰子程序的流程控制,代碼中定義了以下?tīng)顟B(tài):
// 0 = start with printing text
#define START_STATE 0
// 10 = waiting for start shaking
#define WAIT_STATE 10
// 20 = generate random numbers and wait for stop shaking
#define SHAKE_STATE 20
// 30 = display dice #1 value
#define DISPLAY1_STATE 30
// 40 = display dice #2 value
#define DISPLAY2_STATE 40
// 50 = wait for button press to start new game
#define BUTTON_STATE 50
操作順序的詳細(xì)圖形表示如下所示:
狀態(tài)機(jī)實(shí)現(xiàn)
有幾種方法可以實(shí)現(xiàn)狀態(tài)機(jī)。由于該軟件只需要一個(gè)簡(jiǎn)單的狀態(tài)機(jī),因此也可以通過(guò)一個(gè)簡(jiǎn)單的switch()函數(shù)來(lái)實(shí)現(xiàn):
// state machine cases
switch(process_State) {
// ******** START_STATE = start with printing text
case START_STATE :
...
// next state
process_State = WAIT_STATE;
break;
// ******** WAIT_STATE = waiting for acceleration (start shaking)
case WAIT_STATE :
...
process_State = SHAKE_STATE;
break;
// ******** SHAKE_STATE = generate random numbers and wait for stop shaking
case SHAKE_STATE :
...
process_State = DISPLAY1_STATE;
break;
// ******** DISPLAY1_STATE = display dice #1
case DISPLAY1_STATE :
...
process_State = DISPLAY2_STATE;
break;
// ******** DISPLAY2_STATE = display dice #2
case DISPLAY2_STATE :
...
process_State = BUTTON_STATE;
break;
// ******** BUTTON_STATE = wait for button press to start new roll
case BUTTON_STATE :
...
process_State = START_STATE;
break;
}
在每個(gè)“開(kāi)關(guān)狀態(tài)”中,都實(shí)現(xiàn)了相應(yīng)的功能。詳情請(qǐng)查看完整的源代碼。基本上這就是全部。不像一開(kāi)始聽(tīng)起來(lái)那么復(fù)雜,對(duì)吧?
如果你想學(xué)習(xí)如何處理背景圖像,請(qǐng)查看我的“M5Stack Screen Capture”項(xiàng)目或我的“M5Stack Christmas Snow Globe”項(xiàng)目。
震動(dòng)檢測(cè)
集成加速度傳感器 (IMU) 測(cè)量 3 個(gè)軸(X、Y 和 Z)的加速度:
因此,左右晃動(dòng)可以通過(guò)沿 X 軸的加速度來(lái)確定。但不應(yīng)檢測(cè)到敲擊、撞擊或敲擊,只有實(shí)際的搖晃。一種簡(jiǎn)單的方法是在很短的時(shí)間間隔內(nèi)進(jìn)行兩次測(cè)量。然后,這些值的絕對(duì)差異可以用作設(shè)備加速程度的指標(biāo)。方向無(wú)關(guān)緊要(向左或向右),因?yàn)橛?jì)算的是絕對(duì)值。但是,該值也會(huì)檢測(cè)到設(shè)備上的敲擊。為了防止這種情況,可以計(jì)算 10 次測(cè)量的移動(dòng)平均值,從而過(guò)濾掉高頻數(shù)據(jù),如敲擊或敲擊。
非阻塞解決方案
如果你編寫(xiě)一個(gè)函數(shù),以 100ms 的間隔測(cè)量加速度 10 次來(lái)計(jì)算平均值,那么整個(gè)軟件將被阻塞 10*100ms = 1 秒。情況不妙。人們應(yīng)該始終避免這種阻塞功能。與其在函數(shù)內(nèi)部循環(huán)進(jìn)行 10 次測(cè)量,不如讓函數(shù)只進(jìn)行一次測(cè)量,然后將結(jié)果存儲(chǔ)在全局變量中。在狀態(tài)機(jī)內(nèi),函數(shù)在WAIT_STATE和SHAKE_STATE內(nèi)被調(diào)用,這導(dǎo)致?tīng)顟B(tài)機(jī)的非阻塞流。
移動(dòng)平均過(guò)濾功能
通常人們會(huì)通過(guò)將單個(gè)值相加然后將總和除以相加值的數(shù)量來(lái)計(jì)算平均值:
此方法適用于逐塊計(jì)算平均值:您只需將多個(gè)值相加,然后將最后的總和除以值的數(shù)量。對(duì)于下一個(gè)塊,您再次從總結(jié)新值開(kāi)始。但是,如果要計(jì)算每個(gè)新值的平均值(移動(dòng)平均值),則必須刪除列表的第一個(gè)值并在末尾添加新值。編寫(xiě)這樣的方法既麻煩又在數(shù)學(xué)上是不必要的。
另一種(順便說(shuō)一下,在數(shù)學(xué)上相同)方法是將最后計(jì)算的平均值乘以減 1 的值的數(shù)量,然后將新值添加到其中,并將該總和除以要平均的值的數(shù)量:
與存儲(chǔ) 10 個(gè)值的列表相比,此方法速度更快,所需內(nèi)存更少。
從技術(shù)上講,這是一種低通濾波器,其背后的理論幾乎可以變得任意復(fù)雜,但是對(duì)于這個(gè)簡(jiǎn)單的程序,可以通過(guò)反復(fù)試驗(yàn)很好地確定合適的值。要平均的值的數(shù)量值越高,過(guò)濾掉的高頻信號(hào)就越多,但產(chǎn)生的延遲也就越多。檢測(cè)抖動(dòng)的函數(shù)的實(shí)現(xiàn)如下所示:
int mean_accX_n = 8;
.....
float get_horizontal_shaking(){
// two values of X-acceleration
float accX_1, accX_2;
// Y and Z values are needed for function call
float accY, accZ;
// differential value of X-acceleration
float accX_d = 0;
// get the first and the second sensor data
M5.Imu.getAccelData(&accX_1,&accY,&accZ);
delay(100);
M5.Imu.getAccelData(&accX_2,&accY,&accZ);
// calculate the absolute differential value
accX_d = fabs(accX_2 - accX_1);
// building the mean value (Moving average calculation)
mean_accX_d = ((mean_accX_d * (mean_accX_n-1)) + accX_d)/mean_accX_n;
return mean_accX_d;
}
返回值大于 3 表示設(shè)備已搖晃。小于 1 的值表示晃動(dòng)已停止:
有了這個(gè),骰子軟件就可以運(yùn)行了,你可以為酒吧賬單滾動(dòng)了。唯一缺少的是作弊功能。
物聯(lián)網(wǎng)作弊
只需幾行簡(jiǎn)單的代碼,M5StickC 就變成了一個(gè) WiFi 接入點(diǎn):
// WiFi network configuration:
char wifi_ssid[] = "M5StickC-plus";
char wifi_key[] = "1234567890";
IPAddress ip(192, 168, 0, 1);
IPAddress gateway(192, 168, 0, 1);
IPAddress subnet(255, 255, 255, 0);
WiFiClient myclient;
WiFiServer server(80);
void web_server_init(){
WiFi.mode(WIFI_AP);
WiFi.softAP(wifi_ssid, wifi_key);
WiFi.softAPConfig(ip, gateway, subnet);
WiFi.begin();
// Start TCP/IP-Server
server.begin();
}
現(xiàn)在您可以將手機(jī)連接到 M5Stick 創(chuàng)建的 WiFi 接入點(diǎn)。同時(shí),Web 服務(wù)器正在等待您使用瀏覽器連接到 IP 地址。
我已經(jīng)在我的項(xiàng)目“ M5ATOM ENV 迷你數(shù)據(jù)監(jiān)視器”中描述了 Web 服務(wù)器的功能。對(duì)于骰子網(wǎng)頁(yè),我還使用動(dòng)態(tài) HTML 代碼通過(guò)外部 Java 腳本請(qǐng)求包含立方體的值:
<script>
window.onload = function(){
document.getElementById('dice1').innerHTML = dice1value;
document.getElementById('dice2').innerHTML = dice2value;
};
script>
<script type="text/javascript" src="dicevalue.js">script>
擲出的兩個(gè)骰子的值被定義為全局變量。當(dāng) Web 瀏覽器請(qǐng)求 Java 腳本文件“ dicevalue.js ”時(shí),Web 服務(wù)器會(huì)根據(jù)當(dāng)前值生成它:
case GET_dicevalue: {
client.println("HTTP/1.1 200 OK");
client.println("Content-type:application/javascript");
client.println();
client.printf("var dice1value = %c;\n", dice1_html_value);
client.printf("var dice2value = %c;\n", dice2_html_value);
break;
}
其他一切都與我的項(xiàng)目“M5ATOM ENV 迷你數(shù)據(jù)監(jiān)視器”中的描述完全相同。但是,在這段代碼中,我將 Web 服務(wù)器功能外包給了外部文件。這使骰子軟件的代碼保持簡(jiǎn)單和干凈。帶有接入點(diǎn)的 Web 服務(wù)器只需要在 setup() 函數(shù)中初始化,并在每次運(yùn)行時(shí)在 loop() 函數(shù)中調(diào)用:
void setup() {
M5.begin();
...
// init and start the web-server for the dice-web-page
web_server_init();
delay(3000);
}
void loop() {
M5.update();
...
// check for web browser requests
web_server_update();
delay(20);
}
現(xiàn)在你可以帶著空錢包去酒吧和朋友喝一杯。但是請(qǐng)確保 M5Stick 的電池始終充滿電,因?yàn)槿绻腥四贸稣嬲镊蛔?,您必須依靠您的運(yùn)氣而不是您的智能手機(jī)。
反饋
我希望你喜歡這個(gè)簡(jiǎn)短有趣的項(xiàng)目,并且這段代碼可以證明對(duì)你們中的一些人有用。如果您有任何問(wèn)題或意見(jiàn),請(qǐng)隨時(shí)給我留言。
享受擲骰子的樂(lè)趣!
問(wèn)候,
漢斯-君特
- 物聯(lián)網(wǎng)感知技術(shù)及系統(tǒng)應(yīng)用 1次下載
- 基于Arduino的7段顯示數(shù)字骰子
- 具有隨機(jī)功能的簡(jiǎn)單LED骰子
- 什么是智能工廠-物聯(lián)網(wǎng)系統(tǒng) 7次下載
- 物聯(lián)網(wǎng)工程概要設(shè)計(jì)課件下載 0次下載
- 物聯(lián)網(wǎng)工程PCB詳細(xì)設(shè)計(jì)課件下載 0次下載
- 物聯(lián)網(wǎng)工程需求分析課件下載 0次下載
- 物聯(lián)網(wǎng)工程概述課件下載 0次下載
- 工業(yè)物聯(lián)網(wǎng)的詳細(xì)解析工業(yè)物聯(lián)網(wǎng)到底是什么 11次下載
- 物聯(lián)網(wǎng)芯片設(shè)計(jì)應(yīng)該如何降耗
- 如何使用物聯(lián)網(wǎng)操作系統(tǒng)Zephyr實(shí)現(xiàn)“連續(xù)集成”開(kāi)源軟件的詳細(xì)說(shuō)明
- 物聯(lián)網(wǎng)金融系統(tǒng)方案設(shè)計(jì)的詳細(xì)資料說(shuō)明 23次下載
- 物聯(lián)網(wǎng)無(wú)線連接技術(shù)是什么?物聯(lián)網(wǎng)產(chǎn)品的射頻測(cè)試資料概述 26次下載
- 物聯(lián)網(wǎng)是什么?現(xiàn)在物聯(lián)網(wǎng)通信標(biāo)準(zhǔn)和協(xié)議有哪些?物聯(lián)網(wǎng)應(yīng)用的概述
- 物聯(lián)網(wǎng)的真正價(jià)值是什么?
- 物聯(lián)網(wǎng)網(wǎng)關(guān)的類型和功能 1804次閱讀
- 分享一個(gè)棋盤游戲電子骰子電路 2234次閱讀
- 三個(gè)簡(jiǎn)單的電子骰子電路分析 5765次閱讀
- 基于AT89C205構(gòu)建的電子骰子的電路圖 2178次閱讀
- 物聯(lián)網(wǎng)是什么和物聯(lián)網(wǎng)基本架構(gòu) 5697次閱讀
- 如何通過(guò)藍(lán)牙微控制器控制多功能骰子? 2905次閱讀
- 帶反接保護(hù)的電子骰子電路 3381次閱讀
- 具有階梯計(jì)價(jià)功能的物聯(lián)網(wǎng)智能水表的原理及設(shè)計(jì) 1688次閱讀
- LED骰子diy教程 4650次閱讀
- 物聯(lián)網(wǎng)典型的四層架構(gòu)分析 9.3w次閱讀
- 物聯(lián)網(wǎng)的專業(yè)技能在實(shí)際生活中的應(yīng)用 7361次閱讀
- 農(nóng)業(yè)物聯(lián)網(wǎng)的意義_農(nóng)業(yè)物聯(lián)網(wǎng)的功能_農(nóng)業(yè)物聯(lián)網(wǎng)的應(yīng)用 9619次閱讀
- 工業(yè)物聯(lián)網(wǎng)的意義_工業(yè)物聯(lián)網(wǎng)前景分析 1.2w次閱讀
- 蜂窩物聯(lián)網(wǎng)是什么_蜂窩物聯(lián)網(wǎng)建設(shè)意義 1.3w次閱讀
- 驅(qū)動(dòng)電子骰子至少需要幾個(gè)I/O口? 3962次閱讀
下載排行
本周
- 1山景DSP芯片AP8248A2數(shù)據(jù)手冊(cè)
- 1.06 MB | 532次下載 | 免費(fèi)
- 2RK3399完整板原理圖(支持平板,盒子VR)
- 3.28 MB | 339次下載 | 免費(fèi)
- 3TC358743XBG評(píng)估板參考手冊(cè)
- 1.36 MB | 330次下載 | 免費(fèi)
- 4DFM軟件使用教程
- 0.84 MB | 295次下載 | 免費(fèi)
- 5元宇宙深度解析—未來(lái)的未來(lái)-風(fēng)口還是泡沫
- 6.40 MB | 227次下載 | 免費(fèi)
- 6迪文DGUS開(kāi)發(fā)指南
- 31.67 MB | 194次下載 | 免費(fèi)
- 7元宇宙底層硬件系列報(bào)告
- 13.42 MB | 182次下載 | 免費(fèi)
- 8FP5207XR-G1中文應(yīng)用手冊(cè)
- 1.09 MB | 178次下載 | 免費(fèi)
本月
- 1OrCAD10.5下載OrCAD10.5中文版軟件
- 0.00 MB | 234315次下載 | 免費(fèi)
- 2555集成電路應(yīng)用800例(新編版)
- 0.00 MB | 33566次下載 | 免費(fèi)
- 3接口電路圖大全
- 未知 | 30323次下載 | 免費(fèi)
- 4開(kāi)關(guān)電源設(shè)計(jì)實(shí)例指南
- 未知 | 21549次下載 | 免費(fèi)
- 5電氣工程師手冊(cè)免費(fèi)下載(新編第二版pdf電子書(shū))
- 0.00 MB | 15349次下載 | 免費(fèi)
- 6數(shù)字電路基礎(chǔ)pdf(下載)
- 未知 | 13750次下載 | 免費(fèi)
- 7電子制作實(shí)例集錦 下載
- 未知 | 8113次下載 | 免費(fèi)
- 8《LED驅(qū)動(dòng)電路設(shè)計(jì)》 溫德?tīng)栔?/a>
- 0.00 MB | 6656次下載 | 免費(fèi)
總榜
- 1matlab軟件下載入口
- 未知 | 935054次下載 | 免費(fèi)
- 2protel99se軟件下載(可英文版轉(zhuǎn)中文版)
- 78.1 MB | 537798次下載 | 免費(fèi)
- 3MATLAB 7.1 下載 (含軟件介紹)
- 未知 | 420027次下載 | 免費(fèi)
- 4OrCAD10.5下載OrCAD10.5中文版軟件
- 0.00 MB | 234315次下載 | 免費(fèi)
- 5Altium DXP2002下載入口
- 未知 | 233046次下載 | 免費(fèi)
- 6電路仿真軟件multisim 10.0免費(fèi)下載
- 340992 | 191187次下載 | 免費(fèi)
- 7十天學(xué)會(huì)AVR單片機(jī)與C語(yǔ)言視頻教程 下載
- 158M | 183279次下載 | 免費(fèi)
- 8proe5.0野火版下載(中文版免費(fèi)下載)
- 未知 | 138040次下載 | 免費(fèi)
評(píng)論
查看更多