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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4955|回復: 0
打印 上一主題 下一主題
收起左側

微信寵物屋 機智云系統

[復制鏈接]
跳轉到指定樓層
樓主
ID:111475 發表于 2016-3-30 23:15 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
第一章:通信協議分析
                                                      ———以微信寵物屋為例

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











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

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








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








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


可以看到主函數下載完成了一堆初始化之后,在循環值進行了三個函數,第一個和第三個是串口事件處理,第二個是按鍵事件處理(對應之前第一節講的流程圖)。
我們先來看串口事件處理函數MessageHandle(),在這之前,我們需要考慮到串口事件發生的前提是串口已經接收到了數據幀,因此我們需要找到串口再那里接收這些命令的,我們找到串口接收函數,在STM32里串口接收是以串口中斷出現的,而庫函數里所有的中斷都是默認在stm32f10x_it.c下的,所以在c文件下我們可找到void USART1_IRQHandler(void),這就是串口1的中斷接收函數。這段代碼我已經做了詳細注釋,大家可參考上一節的《寵物屋設備端開發指南》下的命令格式和包頭排重約定仔細對照查看:
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) //數據包還沒有接收完
      {
         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收到標志位
            }         
            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;     //已經收到了第二個0xFF            
                  }   
                  else
                  {
                     cmd_flag1 = 0;    //兩個0XFF接收完清標志位
                  }
            }
            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))   //接收的數據包是否完整
         {
            get_one_package = 1; //數據包接收完成標志位
            cmd_flag1 = 0;      
         }                                          
看懂串口接收代碼后,我們回到主函數,鼠標右鍵單擊MessageHandle()選擇gotodifinitionMessageHandle找到該處理函數:
可以看到if(get_one_package)這條語句,只有get_one_package=1的時候下面的程序才會執行,而get_one_package=1就是在串口接收函數里賦值的,表示接收到完整的數據幀。繼續往下看到
















   


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

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

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




















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


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






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

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





      


我們鼠標右鍵 GOTO 到  m_w2m_controlMcu.cmd_tag 里面,可以看到該結構體內容如下:


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

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

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


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

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

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日本特黄a级高清免费大片 成年人黄色小视频 | 羞羞视频网站 | 日韩一区二区三区视频 | 欧美 日韩 国产 成人 | 天天舔天天| 一区二区三区四区在线视频 | 国产网站在线免费观看 | 一区二区三区电影网 | 亚洲免费高清 | 久久av一区二区三区 | 色综合视频 | 国产精品毛片 | 国内自拍视频在线观看 | 精品一区二区三区在线观看国产 | 韩国av电影网 | 狠狠干天天干 | 中文字幕成人av | 亚洲免费网 | 99精品久久久久 | 免费h在线 | 在线一区二区观看 | 国产高清精品一区二区三区 | 中文字幕不卡在线观看 | 亚洲成人在线视频播放 | 啪啪综合网 | 久久久久国产成人精品亚洲午夜 | 色综合av | 欧美中文字幕一区 | 欧美久久不卡 | 欧美激情一区二区 | 亚洲精品日本 | 国产超碰人人爽人人做人人爱 | 久久久.com | 中文字幕精品视频在线观看 | 国产清纯白嫩初高生在线播放视频 | 91久久精品日日躁夜夜躁欧美 | 中文在线一区二区 | 欧美激情在线播放 | 亚洲一区二区三区视频 | 亚洲国产成人精品女人久久久 | 狠狠色狠狠色综合日日92 |