1. 程式人生 > >STM32通過SIM800L向yeelink端上傳資料

STM32通過SIM800L向yeelink端上傳資料

           忙了一個多月,終於完成了一套系統的開發,筆者參與完成了SIM800L向yeelink端上傳資料,以及Andriod客戶端的開發,視訊製作等。裝置演示視訊地址

為:

http://v.youku.com/v_show/id_XMTI2NTM5OTA2NA==.html

另外我們還做了一套更小的板子,因為外觀設計等問題,需要等待。好了,廢話不多說,來說一說SIM800L上傳資料到yeelink中的一些問題,和解決辦法,Andriod

客戶端的,技術含量不是很高,就不再提及。

這裡我們是通過TCP/IP的方式模擬HTTP進行傳送的json格式資料,對傳送HTTP要有所瞭解,不瞭解的可以windows下,IE 裡裝個httpwatch,Linux直接用wireshark,跟蹤一下

就能大致瞭解了。

這裡就以傳送柺杖跌倒標誌位來講述:

const char yeelink1[]="POST /v1.0/device/xxxxx/sensor/xxxxx/datapoint HTTP/1.1\r\n";
const char yeelink2[]="Host: api.yeelink.net\r\n";
const char yeelink3[]="Accept: */*\r\n";
const char yeelink4[]="U-ApiKey:d0fdba9069356c7dc282df3515xxxxxx\r\n";
const char yeelink5[]="Content-Length:13\r\n";
const char yeelink6[]="Content-Type: application/x-www-form-urlencoded\r\n";
const char yeelink7[]="Connection: close\r\n\r\n";
char yeelink8[]="{\"value\":0}\r\n";
const char yeelink9[]="\r\n";
const char yeelink10[]="\x1A\r\n";

這些就是我們要POST的內容(xxx就不公佈了)。

要上傳這些資料到yeelink,我們首先當然是控制SIM800L上網,GSM聯網我們需要:開啟任務,啟用場景等,依次我們用

AT+CSTT

AT+CIICR

AT+CIFSR

AT+CIPSTART="TCP","42.96.164.52","80"

AT+CIPSEND

然後就可以傳送資料了,這些操作倒是沒有什麼,很正常,在上位機除錯也沒有什麼問題,可放到STM32上面,問題來了

(不是挖掘機技術哪家強的問題),有時候資料傳送成功,有時候傳送失敗,還有時候呢不僅僅沒有成功,反而在執行完

指令時,進行AT+CIPSHUT關閉也不成功。首先和大家想到的一樣,那就是延遲的問題,沒錯,確實是延遲的問題,我們

確定一組延遲以後,是可以進行傳送的,可訊號不好的時候又出現傳送不一定成功的時候,而且還會伴隨上面的問題,怎樣

做呢,剛開始是試著去尋找一組都可以用的延遲,自然是越久越穩定,可啟用場景這一步,手冊上說最大達到85s,

這個問題考慮了很久,決定放棄這種方法,決定曲線救國吧,這裡先說明一點,這裡在STM32上除錯GSM是有回顯的

我們怎樣判斷每次輸入的指令成功執行了呢?

第一,先確定輸入指令GSM有應答訊號

這裡採取的方法是迴圈等待,直到連線GSM的串列埠有應答資訊,有的需要一次,有的需要兩次迴圈等待,看具體指令。

試驗中發現,串列埠有時連續傳送兩次,中間有短暫間隔。這裡我們借用微控制器按鍵去抖的經驗,短暫延時後再次判斷

串列埠中資料長度是否變化來解決。

看到有的人是判斷GSM執行指令後,串列埠緩衝區裡面回顯的是否正確來判斷命令是否成功。這裡我不推薦,因為事實上,

比如你的GSM如果已經處於IP GPRSACT狀態了,你再執行AT+CIICR返回錯誤,你卻可以進行下一步的操作。

這裡推薦的方法是執行命令前,先查詢IP所處的狀態,使用命令為:AT+CIPSTATUS,這樣可以在任意狀態下進行。

這裡貼出部分程式碼,這裡沒有使用結構體偏移,源於對STM32編譯器不瞭解,程式粗糙了點

void open_ip(void)
{
    u8 flag=1;
    
    while(flag)
    {
        if(getipstatus("TCP CONNECTING")||getipstatus("IP CONFIG"))
        {
            delay_ms(1000);            
        }else
        if(getipstatus("CONNECT OK"))
        {
                flag=0;            
        }else
        if(getipstatus("TCP CLOSED"))
        {
            usart3_send_str(atcipshut);
            wait_for_answer();    
            wait_for_answer();
        }else
        if(getipstatus("IP STATUS"))
        {
            usart3_send_str(atcipstart);
            wait_for_answer();                    
        }else
        if(getipstatus("IP GPRSACT"))
        {
            usart3_send_str(atcifsr);
            wait_for_answer();                    
        }else
        if(getipstatus("IP START"))
        {
            usart3_send_str(atciicr);
            wait_for_answer();
            wait_for_answer();            
        }else
        if(getipstatus("IP INITIAL"))
        {
            usart3_send_str(atcstt);
            wait_for_answer();
        }
        else{
            usart3_send_str(atcipshut);
            wait_for_answer();
    }
    }
}

筆者實驗發現,都很成功