久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4987|回復(fù): 0
收起左側(cè)

微信寵物屋 機智云系統(tǒng)

[復(fù)制鏈接]
ID:111475 發(fā)表于 2016-3-30 23:15 | 顯示全部樓層 |閱讀模式
第一章:通信協(xié)議分析
                                                      ———以微信寵物屋為例

微信寵物屋是機智云提供的一套完整的基礎(chǔ)例程,在了解相關(guān)通信流程之后,我們可在該程序基礎(chǔ)上開發(fā)自己的程序,實現(xiàn)與云服務(wù)的對接,進而達到遠程控制的目的,接下來我們就來仔細分析下機智云的“M2M”機制到底是如何“跑起來的”。
  第一節(jié):文檔說明部分詳解
第一步:我們打開微信寵物屋程序gokit-mcu-master:看到他的目錄結(jié)構(gòu)如下











其中:MDK_Project即是STM32的程序入口,在分析程序之前我們先來看一下《寵物屋產(chǎn)品設(shè)備端開發(fā)指南》了解一下該程序?qū)崿F(xiàn)的功能和串口協(xié)議的規(guī)定是怎樣的。
首先:我們來看產(chǎn)品信息,該處定義了相關(guān)的數(shù)據(jù)點(如何建立數(shù)據(jù)點請訪問www.gizwits.com)和寵物屋實現(xiàn)的功能,包括:調(diào)節(jié)RGB三色燈、電機轉(zhuǎn)速、紅外探測等。這些大家了解就行。其中需要大家特別注意的是“設(shè)備識別碼”這個關(guān)鍵詞,可以看到微信寵物屋的識別碼是“6f3074fe43894547a4f1314bd7e3ae0b”,機智云對于每一款產(chǎn)品都會生成唯一的識別碼以作區(qū)分,待會我們將在程序中找到定義識別碼的位置。
其次:我們來看產(chǎn)品信息,可以看到流程圖上清楚的介紹了整個協(xié)議工作的流程,簡單分析一下,其實可以分為兩部分處理:
第一部分、按鍵事件發(fā)生:主要用于MCU處理按鍵事件發(fā)生后與WIFI的通訊處理。
第二部分、串口事件發(fā)生:機智云是通過WIFI模塊與MCU以串口通信來實現(xiàn)的,所以下面的這些有關(guān)WIFI的事件都可以歸類為串口事件的發(fā)生,包括:Wifi 發(fā)送控制命令、Wifi 發(fā)送查詢命令、Wifi 發(fā)送心跳命令、Wifi 狀態(tài)更新、外設(shè)狀態(tài)變化。

總體來說,整個系統(tǒng)上電之后的流程如下:
1)MCU 先上電,初始化完成后,給模塊上電;
2) 模塊初始化;
3) 模塊向MCU 詢問必要信息,MCU 返回信息(見協(xié)議舉例);
4) 進入正常工作循環(huán);
a) 模塊給MCU 下發(fā)控制命令(見協(xié)議舉例);
b) MCU 返回確認,表示收到命令,正在執(zhí)行(見協(xié)議舉例);
c) 執(zhí)行完新控制命令后,無論狀態(tài)是否發(fā)生變化,MCU 都需要通知模塊最新狀態(tài)(見       協(xié)議舉例);
d) 若MCU 檢測到環(huán)境屬性變化或者用戶在設(shè)備上按鍵引起的狀態(tài)變化,MCU 需要       通知模塊最新狀態(tài),但是其發(fā)送的頻率不能快于2 秒每次(見協(xié)議舉例);
e) 若環(huán)境狀態(tài)一直不變化,MCU 需要每隔10 分鐘定期主動上報當(dāng)前狀態(tài)f) 模塊會       向MCU 發(fā)送心跳,MCU 收到后按照格式返回即可(見協(xié)議舉例);MCU 連續(xù)180 秒       收不到模塊的數(shù)據(jù),即可認為模塊異常,可以給模塊重新上電;
最后:我們來了解具體通訊協(xié)議的約定,可以看到
命令格式:header(2B)=0xFFFF, len(2B), cmd(1B), sn(1B), flags(2B),DATA(XB),checksum(1B)
說明:
1) 包頭(header)固定為0xFFFF;
2) 長度(len)是指從cmd 開始到整個數(shù)據(jù)包結(jié)束所占用的字節(jié)數(shù);
3) 命令字(cmd)表示具體的命令含義,詳見協(xié)議舉例;
4) 消息序號(sn)由發(fā)送方給出,接收方響應(yīng)命令時需把消息序號返回給發(fā)送方;
5) 標(biāo)志位(flag),本產(chǎn)品填寫默認0;
6) p0 數(shù)據(jù)區(qū)(DATA),詳細參見p0 數(shù)據(jù)區(qū)約定;
7) 檢驗和(checksum)的計算方式為從len~DATA,按字節(jié)求和;
8) 所有發(fā)送的命令都帶有確認,如在200 毫秒內(nèi)沒有收到接收方的響應(yīng),發(fā)送方;應(yīng)重       發(fā),最多重發(fā)3 次;
9) 多于一個字節(jié)的整型數(shù)字以大端字節(jié)序編碼(網(wǎng)絡(luò)字節(jié)序);
10) 數(shù)字均用16 進制表示;
相信這一部分大家都能看懂,這里不再敘述,接下來看到“p0 數(shù)據(jù)區(qū)約定”,實現(xiàn)如下功能:
1)模塊向MUC 發(fā)送控制命令時攜帶p0 命令和命令標(biāo)志位以及可寫數(shù)據(jù)區(qū)
2)MCU 主動發(fā)送狀態(tài)時或者回復(fù)wifi 模塊的狀態(tài)查詢時攜帶p0 命令和完整數(shù)據(jù)區(qū)
3)數(shù)據(jù)區(qū)會自動合并布爾和枚舉變量,且有嚴(yán)格的順序,不可任意改變
怎么來理解這三個功能呢?我們知道在機智云上定義數(shù)據(jù)點完成后,系統(tǒng)會自動生成對應(yīng)的“串口通訊協(xié)議”如下圖所示:
我們下載這份通訊協(xié)議文檔打開,可以看到具體有如下命令:
1)WiFi模組請求設(shè)備信息
2)WiFi模組與設(shè)備MCU的心跳
3)設(shè)備MCU通知WiFi模組進入配置模式
4) 設(shè)備MCU重置WiFi模組
5)WiFi模組向設(shè)備MCU通知WiFi模組工作狀態(tài)的變化
6) WiFi模組請求重啟MCU
7)非法消息通知
8)WiFi模組讀取設(shè)備的當(dāng)前狀態(tài)
9)設(shè)備MCU向WiFi模組主動上報當(dāng)前狀態(tài)
10)WiFi模組控制設(shè)備
這些命令中我們只要具體關(guān)注8、9、10三條命令即可,我們先來找到第10條命令如下:
4)對應(yīng)上面“p0 數(shù)據(jù)區(qū)約定”中的功能1來看,模塊向MUC 發(fā)送控制命令時攜帶p0 命令、命令標(biāo)志位、及可寫數(shù)據(jù)區(qū)三部分命令,至此大家應(yīng)該清楚了,前6位代表p0 命令、attr_flags(1B)代表命令標(biāo)志位、attr_vals(6B)代表可寫數(shù)據(jù)區(qū)。這就告訴了我們編寫mcu代碼時,應(yīng)該怎么樣去識別WIFI發(fā)來的控制命令。那具體要怎么識別呢,往下看協(xié)議的注解:
1. 是否設(shè)置標(biāo)志位(attr_flags)表示相關(guān)的數(shù)據(jù)值是否為有效值,相關(guān)的標(biāo)志位為1表示值有效,為0表示值無效,
從右到左的標(biāo)志位依次為:
bit0: 設(shè)置LED_OnOff
bit1: 設(shè)置LED_Color
bit2: 設(shè)置LED_R
bit3: 設(shè)置LED_G
bit4: 設(shè)置LED_B
bit5: 設(shè)置Motor_Speed
這里可以清楚的看到attr_flags占1B字節(jié),其中bit0代表設(shè)置LED_OnOff......bit5: 設(shè)置Motor_Speed,那么對于我們的mcu接收到WIFI發(fā)來的控制命令后,我們通過識別attr_flags的每一位即可對應(yīng)出需要控制的設(shè)備,如果還看不懂,一會我們分析mcu程序。
看完標(biāo)志位之后我們看attr_vals(6B)  即可寫數(shù)據(jù)區(qū):








5)這里可以清楚的看到,只有相關(guān)的設(shè)置標(biāo)志位(attr_flags)為1時,數(shù)據(jù)值才是有效的,需要特別注意的是“p0 數(shù)據(jù)區(qū)約定”約定第三條,數(shù)據(jù)區(qū)會自動合并布爾和枚舉變量,且有嚴(yán)格的順序,不可任意改變。對應(yīng)上面的“byte0”合并了“bool”和“enum”類型。
至此p0 數(shù)據(jù)區(qū)約定 到此結(jié)束,后面在MCU程序中會對應(yīng)具體代碼講解。
《寵物屋設(shè)備端開發(fā)指南》通訊寫一部分最后一個包頭排重約定
原則:我們的包頭是兩個連續(xù)的FF FF,如果此包中還有某字節(jié)出現(xiàn)FF,僅在傳輸和接收的時候處理,其他環(huán)節(jié)按正常數(shù)據(jù)處理;
舉例:
1) 某設(shè)備上報狀態(tài)幀:FF FF 00 15 05 03 00 00 04 01 01 02 03 01 00 00 00 32 FF 20 00 03 7D, 除包頭外,出現(xiàn)了FF;
2) 在程序內(nèi)部,作為正常的數(shù)據(jù)去處理;
3) 當(dāng)需要傳輸時,將除包頭外的FF后,增加一個55字節(jié),其他不變;
4) 將上述數(shù)據(jù)處理成:FF FF 00 15 05 03 00 00 04 01 01 02 03 01 00 00 00 32 FF 55 20 00 03 7D,長度不變,校驗碼不變;
5) 接收方在接收過程中,如果收到字節(jié)是FF,及判斷第二個字節(jié)是否也是FF,如果是FF,表示一個新包,按照新包處理;
6) 如果第二個字節(jié)是55,直接丟棄,不算接收長度,繼續(xù)接收下一個字節(jié);
7) 直到按照長度接收完,或者碰到下一個連續(xù)的FF FF;
這部分代碼出現(xiàn)在mcu與WIFI 的串口通訊部分,所以我們一會找到mcu的串口接收程序,簡而分析,即可清楚什么是包頭排重約定。
《寵物屋設(shè)備端開發(fā)指南》第4部分協(xié)議舉例,下節(jié)配合mcu程序講解。








第二節(jié):MCU程序詳解(STM32)
注意:此節(jié)的分析需要讀者有一定的STM32開發(fā)能力,如果不具備,請先學(xué)習(xí)STM32。
打開MCU程序,在main.c下我們可以看到這樣一段注釋:
意思已經(jīng)很清楚了,大部分的命令代碼機智云已經(jīng)為我們實現(xiàn)了,這也是我在講解《微信寵物屋-機智云接入串口通信協(xié)議文檔》命令時說只需要關(guān)注8、9、10三條指令的原因了,這三條指令對應(yīng)在protocol.c下的CmdSendMcuP0和CmdReportModuleStatus這兩個函數(shù)下,即我們開發(fā)自己的程序時只需關(guān)注這兩個函數(shù)即可。
首選來看主函數(shù):


可以看到主函數(shù)下載完成了一堆初始化之后,在循環(huán)值進行了三個函數(shù),第一個和第三個是串口事件處理,第二個是按鍵事件處理(對應(yīng)之前第一節(jié)講的流程圖)。
我們先來看串口事件處理函數(shù)MessageHandle(),在這之前,我們需要考慮到串口事件發(fā)生的前提是串口已經(jīng)接收到了數(shù)據(jù)幀,因此我們需要找到串口再那里接收這些命令的,我們找到串口接收函數(shù),在STM32里串口接收是以串口中斷出現(xiàn)的,而庫函數(shù)里所有的中斷都是默認在stm32f10x_it.c下的,所以在c文件下我們可找到void USART1_IRQHandler(void),這就是串口1的中斷接收函數(shù)。這段代碼我已經(jīng)做了詳細注釋,大家可參考上一節(jié)的《寵物屋設(shè)備端開發(fā)指南》下的命令格式和包頭排重約定仔細對照查看:
void USART1_IRQHandler(void)
{  
   uint8_t    vlue;
   short         i;

  if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
  {
   USART_ClearITPendingBit(USART1,USART_IT_RXNE);
   vlue = USART_ReceiveData(USART1);
   if(get_one_package ==0) //數(shù)據(jù)包還沒有接收完
      {
         if(cmd_flag1 ==0)   //初始化為0
         {
            if(vlue == 0xff)//接收到第一個0xff
            {   
               uart_Count = 0;                  
               uart_buf[uart_Count]=vlue;    //uart_buf[0]=0xff
                  uart_Count++;   
                  cmd_flag1 = 1;          //第一個0xff收到標(biāo)志位
            }         
            return ;  //如果沒收到返回
         }
         if(cmd_flag2 ==0)
         {
            if(cmd_flag2)                     //cmd_flag2=1
            {
                  uart_buf[uart_Count]=vlue;
                  uart_Count++;
                  if(uart_buf[1] == 0xff)      
                  {
                     cmd_flag2 = 1;     //已經(jīng)收到了第二個0xFF            
                  }   
                  else
                  {
                     cmd_flag1 = 0;    //兩個0XFF接收完清標(biāo)志位
                  }
            }
            cmd_flag2 = 1;
         }
         uart_buf[uart_Count] = vlue;
         if(uart_Count >=4 && uart_buf[uart_Count] == 0x55 && uart_buf[uart_Count-1] == 0xFF){}  //包頭排重
         else uart_Count++;
         if(uart_Count == 0x04)
         {
            cmd_len = uart_buf[2]*256 +  uart_buf[3];                                             
         }
         if(uart_Count ==  (cmd_len + 4))   //接收的數(shù)據(jù)包是否完整
         {
            get_one_package = 1; //數(shù)據(jù)包接收完成標(biāo)志位
            cmd_flag1 = 0;      
         }                                          
看懂串口接收代碼后,我們回到主函數(shù),鼠標(biāo)右鍵單擊MessageHandle()選擇gotodifinitionMessageHandle找到該處理函數(shù):
可以看到if(get_one_package)這條語句,只有g(shù)et_one_package=1的時候下面的程序才會執(zhí)行,而get_one_package=1就是在串口接收函數(shù)里賦值的,表示接收到完整的數(shù)據(jù)幀。繼續(xù)往下看到
















   


這個switch語句下的各種命令可以對應(yīng)在《《微信寵物屋-機智云接入串口通信協(xié)議文檔》》下的命令列表中找到,前面說過這里面大部分命令機智云已經(jīng)幫我們實現(xiàn)了,我們只需要關(guān)注兩個函數(shù)即可,這兩個函數(shù)就在這個switch下面:

其實說的在簡單一點:我們只需要關(guān)注控制命令這一個函數(shù)即可
不信大家可以進入到void       CmdReportModuleStatus(uint8_t *buf) 這個函數(shù)下看看都做了哪些工作:

從注釋也可以看出這個函數(shù)只是描述WIFI狀態(tài)變化的函數(shù),比如我們連接的是AirLink模式還是softap模式,如果你想?yún)^(qū)分,就在這段代碼下添加狀態(tài)指示程序即可,我們不做過多講解,重點用來解釋控制命令函數(shù)void       CmdSendMcuP0(uint8_t *buf)
大家拿到開發(fā)板之后,應(yīng)該都知道第一步需要按下按鍵去配置WIFI連接到云端,才能實現(xiàn)遠程控制,所以在講解控制命令函數(shù)void       CmdSendMcuP0(uint8_t *buf)之前,我們先來看看通過按鍵配置開發(fā)板的這些程序在哪里,既然是按鍵配置,那肯定是在按鍵處理函數(shù)里找嘍,我們回到主函數(shù)下,找到按鍵處理函數(shù)       KeyHandle();         鼠標(biāo)右鍵單擊 選擇 goto        difinition KeyHandle,可以看到




















這里代碼已經(jīng)很清楚了,就不做過多解釋,這里需要大家思考的地方是,按鍵的長按和短按是怎么實現(xiàn)的呢?這里告訴大家,本mcu程序定義了定時器3中斷,去判斷按鍵的長按與短按,超過2秒即認為是長按,既然是定時器中斷函數(shù),那肯定是在stm32f10x_it.c下面嘍,我們找到它,看看它的函數(shù)原型void TIM3_IRQHandler(void) :(這部分代碼我在原來的基礎(chǔ)上做了更多的注解,相信大家都能看懂的)


了解的開發(fā)板配置的代碼后,我們在回頭看控制命令函數(shù)void       CmdSendMcuP0(uint8_t *buf),這是最重點的部分啦,我們復(fù)制其中的重點代碼做詳細講解。






這部分代碼大體的工作流程是:如果串口0傳來了數(shù)據(jù)(buf != NULL),先調(diào)用memcpy函數(shù)將其拷貝到m_w2m_controlMcu 結(jié)構(gòu)體中去,其中結(jié)構(gòu)體成員m_w2m_controlMcu.sub_cmd 是命令標(biāo)志位,如果為SUB_CMD_REQUIRE_STATUS(0x02)則表示查詢命令,當(dāng)即上報當(dāng)前的狀態(tài)到服務(wù)器,如果為SUB_CMD_CONTROL_MC(0x01)則表示控制命令,控制部分就是我們需要重點實現(xiàn)的了。既然是控制部分,那肯定要和我們之前講的《微信寵物屋-機智云接入串口通信協(xié)議文檔.pdf》中的4.10節(jié)《WIFI模塊控制設(shè)備》相聯(lián)系起來了,

我們之前講過這部分 最重要的就是attr_flags(1B) 、attr_vals(6B)這兩位;忘記的同學(xué)請返回前面看一看。這兩位是怎么對應(yīng)程序的呢?我們來看





      


我們鼠標(biāo)右鍵 GOTO 到  m_w2m_controlMcu.cmd_tag 里面,可以看到該結(jié)構(gòu)體內(nèi)容如下:


現(xiàn)在是不是已經(jīng)和《微信寵物屋-機智云接入串口通信協(xié)議文檔.pdf》中的4.10節(jié)《WIFI模塊控制設(shè)備》對應(yīng)起來了,哈哈,我們接著往下看程序

前面我們已經(jīng)知道程序里的cmd_tag就對應(yīng)《微信寵物屋-機智云接入串口通信協(xié)議文檔.pdf》中的4.10節(jié)《WIFI模塊控制設(shè)備》中的attr_flags(1B),是用來選擇控制哪一位的,在文檔中我們可以看到attr_flags的第0位是用來選擇控制LED燈開關(guān)的,即只要設(shè)置了第0位為1就表示要控制LED等開關(guān)了,如下所示:

對應(yīng)程序中
if((m_w2m_controlMcu.cmd_tag & 0x01) == 0x01)
即標(biāo)志第0位為1,接下來就可以控制LED燈的開關(guān)了,我們接著程序往下看;


這段程序就控制了LED燈的開關(guān),即cmd_byte的第0位為1表示燈開,為0表示燈關(guān)。
這對應(yīng)《微信寵物屋-機智云接入串口通信協(xié)議文檔.pdf》中的4.10節(jié)《WIFI模塊控制設(shè)備》中的attr_vals(6B),即設(shè)置數(shù)據(jù)位,如下所示:
可以清楚的看到只要控制byte0(0x07)的第0位就可以控制LED燈了,第一位是用來控制LED顏色的。
這里需要說明的是一般設(shè)置數(shù)據(jù)位的數(shù)據(jù)包的byte0 是用來控制bool型變量和枚舉類型變量的了,應(yīng)為機智云默認是把bool變量和枚舉類型合并處理的。

下面的程序基本和上面一樣了,只要大家看懂了《微信寵物屋-機智云接入串口通信協(xié)議文檔.pdf》中的4.10節(jié)《WIFI模塊控制設(shè)備》中的attr_flags(1B) 、attr_vals(6B)這兩位和程序代碼中的cmd_tag、status_w的對應(yīng)關(guān)系就能自己編寫控制程序了。

回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 四虎影音 | 亚洲精品久久久久中文字幕欢迎你 | 国产一区不卡 | av在线电影网站 | 亚洲欧美日韩精品久久亚洲区 | 日韩精品一区二区三区视频播放 | 欧美精品一二区 | 久久久久国产一区二区三区四区 | 老头搡老女人毛片视频在线看 | 免费视频久久久久 | 国产一区二区在线视频 | 夜夜骑天天干 | 久久手机在线视频 | 国产精品久久久久久久久久免费看 | 久久久久亚洲国产| 成人a视频片观看免费 | 在线成人 | 国产高清在线精品一区二区三区 | 亚洲女人天堂成人av在线 | 天天干天天操天天看 | 欧美特级黄色 | 9191在线观看| 国产91 在线播放 | 日本电影韩国电影免费观看 | 亚洲综合婷婷 | 狠狠色综合久久丁香婷婷 | 国产精品中文字幕一区二区三区 | jav成人av免费播放 | 免费电影av | 欧洲亚洲视频 | 国产日产欧产精品精品推荐蛮挑 | 影音先锋成人资源 | 狠狠操网站 | 韩日精品一区 | 91精品国产欧美一区二区 | 日本在线播放一区二区 | 国产女人叫床高潮大片免费 | 国产精品美女视频 | 一区在线播放 | 国产精品99久久久久久www | 成年人精品视频在线观看 |