AT指令控制GSM/GPRS模塊上網鏈接服務器

如今已是3G、4G的天下,但古老的GSM模式中有一個GPRS數據承載服務,是在2G網絡下對上網需求的優化。java

##GSM和GPRS## GSM是全球移動通信系統Global System of Mobile communication,分屬於2G通訊。linux

GPRS是Gerneral Packer Radio Service的英文縮寫,中文譯爲通用無線分組業務,具體來說,GPRS是一項高速數據處理的科技,即以分組的「形式」把數據傳送到用戶手上。數據庫

GPRS是在GSM系統上發展出來的一種新的承載業務,目的是爲GSM用戶提供分組形式的數據業務。GPRS採用與GSM一樣的無線調製標準、頻帶、突發結構、跳頻規則以及一樣的TDMA幀結構。編程

GPRS容許用戶在端到端分組模式下發送和接收數據,而不須要利用電路交換模式的網絡資源,從而提供了一種高效、低成本的無線分組數據業務。服務器

##AT指令控制## 部分GPRS模塊內置了TCP/IP協議棧,能夠很方便的經過廠家擴展的AT指令直接進行TCP或UDP通訊。網絡

這是在RTOS(RT-Thread Operating System)裏面的一段控制Zigbee模塊用GPRS通訊方式和服務器通訊的代碼:數據結構

<!-- lang: cpp -->
void thread_gsm_entry(void *parameter)
{
uint16_t i = 0;

gsm_init_hw("uart3");

rt_kprintf("gsm init hardware success \n");

thread_gsm_at = rt_thread_create("gsm_at",
                                 thread_gsm_at_entry, RT_NULL,
                                 1024,
                                 10, 10);

if (thread_gsm_at != RT_NULL)
{ rt_thread_startup(thread_gsm_at); }

gsm_power_switch();
rt_thread_delay(RT_TICK_PER_SECOND * 7);

for (i = 0; i < 5; i++)
{
    rt_device_write(gsm_dev, 0, "AT\r\n", strlen("AT\r\n")); //測試鏈接是否正確
    rt_thread_delay(RT_TICK_PER_SECOND * 1);
}

for (i = 0; i < 1; i++)
{
    rt_device_write(gsm_dev, 0, "ATE1\r\n", strlen("ATE1\r\n")); //打開回顯
    rt_thread_delay(RT_TICK_PER_SECOND * 1);
}

for (i = 0; i < 5; i++)
{
    rt_device_write(gsm_dev, 0, "AT+CSQ\r\n", strlen("AT+CSQ\r\n")); //檢查信號
    rt_thread_delay(RT_TICK_PER_SECOND * 1);
}

for (i = 0; i < 5; i++)
{
    rt_device_write(gsm_dev, 0, "AT+CGREG?\r\n", strlen("AT+CGREG?\r\n"));//獲取小區環境
    rt_thread_delay(RT_TICK_PER_SECOND * 1);
}

for (i = 0; i < 1; i++)
{
    rt_device_write(gsm_dev, 0, "AT+CGATT?\r\n", strlen("AT+CGATT?\r\n"));
    rt_thread_delay(RT_TICK_PER_SECOND * 3); //激活
}

for (i = 0; i < 1; i++)
{
    rt_device_write(gsm_dev, 0, "AT+CSTT\r\n", strlen("AT+CSTT\r\n"));
    rt_thread_delay(RT_TICK_PER_SECOND * 5);
}

for (i = 0; i < 1; i++)
{
    rt_device_write(gsm_dev, 0, "AT+CIICR\r\n", strlen("AT+CIICR\r\n"));
    rt_thread_delay(RT_TICK_PER_SECOND * 5);
}

for (i = 0; i < 1; i++)
{
    rt_device_write(gsm_dev, 0, "AT+CIFSR\r\n", strlen("AT+CIFSR\r\n"));
    rt_thread_delay(RT_TICK_PER_SECOND * 1);
}

rt_device_write(gsm_dev,
                0,
                "AT+CIPSTART=\"TCP\",\"202.201.1.49\",12345\r\n",
                strlen("AT+CIPSTART=\"TCP\",\"202.201.1.49\",12345\r\n"));
rt_thread_delay(RT_TICK_PER_SECOND * 5);

rt_device_write(gsm_dev, 0, "AT+CIPSEND=6\r\n", strlen("AT+CIPSEND=6\r\n"));
rt_thread_delay(RT_TICK_PER_SECOND * 3);

rt_device_write(gsm_dev, 0, "DEMO\r\n", strlen("DEMO\r\n"));
rt_thread_delay(RT_TICK_PER_SECOND * 5);

gsm_inited = RT_TRUE;
}

##AT指令步驟和做用##多線程

AT指令的步驟和做用以下所示:app

  1. AT 測試鏈接是否正確
  2. ATE1 打開回顯
  3. AT+CSQ 返回值是信號質量,越大越質量越好。
  4. AT+CGREG 能夠查詢GPRS狀態 通常註冊上運營商,附着GPRS都是自動進行 查詢模塊是否有註冊網絡
  5. AT+CGATT 開機後,若是「AT+CGATT?」命令的返回值爲1,說明SIM卡已經開通了GRPS服務
  6. AT+CSTT 設置APN
  7. AT+CIICR 激活移動場景
  8. AT+CIFSR 得到本地IP地址
  9. AT+CIPSTART="TCP","202.201.xx.xx",12345\r\n 創建TCP鏈接
  10. AT+CIPSEND=6 開始發送數據,數據長度爲6
  11. 發送測試數據「DEMO\r\n」

##服務器端##socket

服務器採用CentOS操做系統,安裝JVM。由於GPRS來的數據是TCP報文格式,能夠採用Socket編程進行接收,接收到的數據能夠插入到數據庫中進行保存。這樣就能夠保存和檢索傳感器節點的採樣數據。

Server端代碼採用Java編寫,很容易。

<!-- lang: java -->
 import java.net.*;
import java.io.*;
public class Server
{
private ServerSocket ss;
private Socket socket;
private BufferedReader in;
private PrintWriter out;
public Server()
{
try
{
ss = new ServerSocket(12345);
socket = ss.accept();
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(),true);
while (true)
{
String line = in.readLine();
System.out.println("Monitoring data :" + line);
//out.close();
// in.close();
//socket.close();
}
ss.close();
}
catch (IOException e)
{}
}
public static void main(String[] args)
{
new Server();
}
}

須要注意的是千萬不要使用out.println,可能會阻塞通訊。

socket = ss.accept()要放在while循環外面持續接收數據。

也不要關閉socket和in輸入流。Zigbee傳來的數據是一個每隔3S的數據流。

在此輸入圖片描述

##RTOS簡介[1]##

RT-Threayd RTOS是一款來自中國的開源實時操做系統,由國內一些專業開發人員開發、維護。它不單單是一款高效、穩定的實時核心,也是一套面向嵌入式系統的軟件平臺,覆蓋了全搶佔的實時操做系統內核,小巧而與底層具體實現無關的文件系統,輕型的TCP/IP協議棧以及輕型的多窗口多線程圖形用戶界面。

##RTOS應用##

這個例子裏面有三個任務(進程):一個是DEMO進程,一個是RF進程,一個是GSM進程。咱們看看任務的寫法:

<!-- lang: cpp -->
//設置和DEMO進程相關的堆棧、數據結構和聲明相關的函數
ALIGN(RT_ALIGN_SIZE)  //DEMO線程,點燈線程
static rt_uint8_t demo_stack[ 2048 ];
static struct rt_thread thread_demo; 
extern void thread_demo_entry(void *parameter);

ALIGN(RT_ALIGN_SIZE)  //RF線程,接收Zigbee分節點的數據,經過GPRS與Server Socket通訊
static rt_uint8_t rf_stack[ 2048 ];
static struct rt_thread thread_rf;
void thread_rf_entry(void *parameter);

ALIGN(RT_ALIGN_SIZE)  //GSM線程,初始化GSM設置,初次通訊,發送「DEMO」字符。
static rt_uint8_t gsm_stack[ 2048 ];
static struct rt_thread thread_gsm; 
void thread_gsm_entry(void *parameter);

int rt_application_init(void)
{
rt_err_t result;

/* init demo thread */
result = rt_thread_init(&thread_demo,
                        "demo",
                        thread_demo_entry,
                        RT_NULL,
                        (rt_uint8_t*)&demo_stack[0],
                        sizeof(demo_stack),
                        30,
                        5);
if (result == RT_EOK)
{
    rt_thread_startup(&thread_demo);
}

/* init rf thread */
result = rt_thread_init(&thread_rf,
                        "rf",
                        thread_rf_entry,
                        RT_NULL,
                        (rt_uint8_t*)&rf_stack[0],
                        sizeof(rf_stack),
                        10,
                        5);
if (result == RT_EOK)
{
    rt_thread_startup(&thread_rf);
}

/* init gsm thread */
result = rt_thread_init(&thread_gsm,
                        "gsm",
                        thread_gsm_entry,
                        RT_NULL,
                        (rt_uint8_t*)&gsm_stack[0],
                        sizeof(gsm_stack),
                        20,
                        5);
if (result == RT_EOK)
{
    rt_thread_startup(&thread_gsm);
}
 return 0;
}

##核心收據收發##

<!-- lang: cpp -->
if (gsm_inited)
        {
            rt_device_write(gsm_dev, 0, "AT+CIPSEND=", strlen("AT+CIPSEND="));
            rt_device_write(gsm_dev, 0, num_temp, strlen(num_temp));
            rt_device_write(gsm_dev, 0, "\r\n", strlen("\r\n"));

            rt_thread_delay(RT_TICK_PER_SECOND * 1);

            rt_device_write(gsm_dev, 0, data_temp, strlen(data_temp));

            rt_thread_delay(RT_TICK_PER_SECOND * 3);
        }

其中gsm_inited在GSM線程中被置位(gsm_inited = RT_TRUE),代表模塊調試和初始化完畢,開始收發數據。

這是在RF線程(任務)中寫的數據核心收發程序,data_temp中存儲的是節點發來的數據, rt_device_write(gsm_dev, 0, data_temp, strlen(data_temp))使得數據傳到服務器上。

##Reference##

[1].http://www.rt-thread.org/

[2].http://www.linuxidc.com/Linux/2012-09/69974.htm

相關文章
相關標籤/搜索