目录
介绍
Sim900A
SIM900支持GPRS连接到嵌入式应用。
它广泛用于IoT(物联网)嵌入式应用程序,其中每个传感器都连接到服务器,我们可以通过互联网控制它们。
GSM / GPRS模块使用USART通信与微控制器或PC终端通信。AT命令用于以不同的模式配置模块,并执行各种功能,如呼叫,向站点发布数据等。
连接图
sim900A GPRS模块与MSP-EXP430G2 TI Launchpad连接
注意:对于TI Launchpad板,P1.1是Rx引脚,P1.2是硬件串口时的Tx引脚。这里,我们使用的是硬件串口,因此P1.1是Rx引脚,P1.2是Tx引脚。
当跳线定位于软件串行时,P1.1作为Tx引脚,P1.2作为Rx引脚。
Adafruit IO
Adafrut IO提供了一个IOT平台,可以创建仪表板,响应从/向服务器发送/接收的数据。
只需注册即可使用Adafruit IO服务并创建自己的仪表板。
按照下面给出的图像序列创建自己的仪表板和链接到它的源。图像不言自明,易于理解。
您可以添加到仪表板中的各种块,我们将使用切换块作为下面给出的示例。
单击“创建”后,单击列表中仪表板的名称。
单击“添加新块”图标。
单击“创建”。
例
- 通过Web服务器进行LED控制(ON / OFF)。(GET)
- 将LED(ON / OFF)的状态发送到Web服务器。(POST)
在这里,我们将使用HTTP GET方法作为示例1.启动板上的LED将通过Adafruit IO网站上的切换开关进行控制。
例如2,我们将使用HTTP POST方法。切换开关用于打开Launchpad板上的ON / OFF LED,LED的状态将发送到Adafruit IO服务器,后者又会更改仪表板上切换开关的状态。
我们将使用带有标准SIM卡的Sim900A通过GPRS访问互联网。
我们将使用Adafruit IO服务器。
使用切换块创建仪表板,如上图所示。您可以为仪表板和Feed选择您喜欢的名称。
在仪表板上进行的更改将反映在Feed中。您可以转到供稿页面,您将看到与其上的仪表板值(在本例中为ON / OFF)对应的值及其时间戳。
现在我们准备将数据POST到此服务器并GET(读取)其中的最后一个数据。
对于POST,我们需要使用以下格式的URL:
io.adafruit.com/api/v2/YourUserName/feeds/FeedKey/data? x-aio-key=YourAIOKey
接下来是格式的数据
{“value”: “OFF”,”created_at”: “20:00:01″,”lat”: 0,”lon”: 0,”ele”: 0,”epoch”: 0}
如果要发送ON而不是ON,请将OFF替换为ON。
created_at时间无关紧要,服务器使用它来计算到达时间。但是,created_at值不能像lat,lon值那样保留为0。
对于GET,我们需要使用以下格式的URL:
io.adafruit.com/api/v2/YourUserName/feeds/FeedKey/data/last?x-aio-key=YourAIOKey
注意: MSP-EXP430G2 TI Launchpad主板具有512字节的RAM,可轻松上传,尤其是在使用不同库时。有时您需要串行缓冲区足够大以包含所需的数据,并且您必须修改串行库的缓冲区大小。在做这些事情时,我们必须确保代码不会使用超过70%的RAM。这可能导致代码以不稳定的方式工作,有时运行良好并且在其他方面失败。
有些时候RAM使用率可能会超过70%并且代码将完全正常工作,并且即使RAM使用率为65%,代码也无法工作。
在这种情况下,可能需要对缓冲区大小和/或变量进行一些试验和错误。
示例1的程序
volatile bool a=HIGH;
volatile bool flag = LOW;
void flush_rx_buffer() /* Flush out the data in the receive buffer*/
{char c;
while(Serial.available()!=0)
{
c = Serial.read();
}
}
void read_rx_buffer()
{
int8_t i=0;
char rx_buffer[90];
memset(rx_buffer,0,90);
while(Serial.available()!=0) /* If data is available on serial port */
{
rx_buffer[i] = Serial.read(); /* Copy received data to buffer for later use */
i++;
} if( strstr(rx_buffer, "\"value\":\"OFF\"")!=0 ) /* If status of switch at server is OFF */
{
digitalWrite(2, LOW); /* Turn OFF the LED1 */
}else if( strstr(rx_buffer, "\"value\":\"ON\"")!=0 ) /* If status of switch at server is ON */
{
digitalWrite(2, HIGH); /* Turn ON the LED1 */
} else
{
digitalWrite(14, a); /* Toggle LED2 if neither ON or OFF received */
a = !a;
}
flag = HIGH;
}
void setup() {
Serial.begin(9600); /* Define baud rate for serial communication */
pinMode(2, OUTPUT); /* LED1 for status of control switch */
pinMode(14, OUTPUT); /* LED2 for error */
digitalWrite(2, LOW);
digitalWrite(14, LOW);
}
void loop() {
char data[70];
memset(data,0,70);
char user[15] = " "; /* Your User Name for Adafruit IO account */char feed[10] = " "; /* Name of the feed you created */char key[34] = " "; /* Your Adafruit IO key */
Serial.print("HTTP get method : \n");
/* Configure bearer profile 1 */if(flag == HIGH)
{
delay(7000);
flag = LOW;
}
Serial.println("AT+SAPBR=0,1"); /* Close GPRS context */
delay(700);
Serial.println("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\""); /* Connection type GPRS */
delay(700);
Serial.println("AT+SAPBR=3,1,\"APN\",\"TATA.DOCOMO.INTERNET\""); /* APN of the provider */
delay(700);
Serial.println("AT+SAPBR=1,1"); /* Open GPRS context */
delay(700);
Serial.println("AT+HTTPTERM"); /* Terminate HTTP service */
delay(700);
Serial.println("AT+HTTPINIT"); /* Initialize HTTP service */
delay(700);
Serial.println("AT+HTTPPARA=\"CID\",1"); /* Set parameters for HTTP session */
delay(700);
Serial.print("AT+HTTPPARA=\"URL\",\"io.adafruit.com/api/v2/");
sprintf(data, "%s/feeds/", user);
Serial.print(data);
memset(data,0,70);
sprintf(data, "%s/data/last?", feed);
Serial.print(data);
memset(data,0,70);
余下程序:
示例2的程序
volatile char *switch_state;
volatile bool state;
volatile bool interrupt_flag;
void setup() {
Serial.begin(9600); /* Define baud rate for serial communication */
pinMode(5, INPUT_PULLUP); /* PUSH2 switch for changing toggling switch */
pinMode(2, OUTPUT); /* LED for displaying state of switch */
digitalWrite(2, LOW);
attachInterrupt(5, control, FALLING); /* Interrupt on falling edge on pin 5 */
state = HIGH;
interrupt_flag = LOW;
switch_state = (char *)"OFF";
}
void loop() {
char data[80];
memset(data,0,80);
char feed_key[10] = " "; /* Name of the feed you created */char user_name[14] = " "; /* Your User Name for Adafruit IO account */char key[34] = " "; /* Your Adafruit IO key */if(interrupt_flag == HIGH)
{
delay(7000);
interrupt_flag = LOW;
}
Serial.println("HTTP post method :");
delay(700);
if(interrupt_flag == HIGH)
{
delay(7000);
interrupt_flag = LOW;
}
Serial.println("ATE0");
delay(700);
if(interrupt_flag == HIGH)
{
delay(7000);
interrupt_flag = LOW;
}/* Configure bearer profile 1 */
Serial.println("AT+SAPBR=0,1"); /* Close GPRS context */
delay(700);
if(interrupt_flag == HIGH)
{
delay(7000);
interrupt_flag = LOW;
}
Serial.println("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\""); /* Connection type GPRS */
delay(700);
if(interrupt_flag == HIGH)
{
delay(7000);
interrupt_flag = LOW;
}
Serial.println("AT+SAPBR=3,1,\"APN\",\"TATA.DOCOMO.INTERNET\""); /* APN of the provider */
delay(700);
if(interrupt_flag == HIGH)
{
delay(7000);
interrupt_flag = LOW;
}
Serial.println("AT+SAPBR=1,1"); /* Open GPRS context */
delay(700);
if(interrupt_flag == HIGH)
{
delay(7000);
interrupt_flag = LOW;
}
Serial.println("AT+HTTPTERM"); /* Terminate HTTP service */
delay(700);
if(interrupt_flag == HIGH)
{
delay(7000);
interrupt_flag = LOW;
}
Serial.println("AT+HTTPINIT"); /* Initialize HTTP service */
delay(700);
if(interrupt_flag == HIGH)
{
delay(7000);
interrupt_flag = LOW;
}
Serial.print("AT+HTTPPARA=\"URL\",\"io.adafruit.com/api/v2/");
sprintf(data, "%s/feeds/", user_name);
Serial.print(data);
memset(data,0,80);
sprintf(data, "%s/data?x-aio-key", feed_key);
Serial.print(data);
memset(data,0,80);
sprintf(data, "=%s\"", key);
Serial.println(data); /* Set parameters for HTTP session */
delay(700);
memset(data,0,80);
if(interrupt_flag == HIGH)
{
delay(7000);
interrupt_flag = LOW;
}
Serial.println("AT+HTTPPARA=\"CONTENT\",\"application/json\"");
delay(700);
if(interrupt_flag == HIGH)
{
delay(7000);
interrupt_flag = LOW;
}
Serial.println("AT+HTTPSCONT");
delay(700);
if(interrupt_flag == HIGH)
{
delay(7000);
interrupt_flag = LOW;
}
Serial.println("AT+HTTPPARA=\"CID\",1"); /* Set parameters for HTTP session */
delay(700);
sprintf(data, "{\"value\": \"%s\",\"created_at\": \"20:00:01\",\"lat\": 0,\"lon\": 0,\"ele\": 0,\"epoch\": 0}", switch_state);
if(interrupt_flag == HIGH)
{
delay(7000);
interrupt_flag = LOW;
}
Serial.println("AT+HTTPDATA=100,10000"); /* POST data of size (max) 100 Bytes with maximum latency time of 10seconds for inputting the data*/
delay(2000);
if(interrupt_flag == HIGH)
{
delay(7000);
interrupt_flag = LOW;
}
Serial.println(data); /* Data to be sent */
delay(10000);
if(interrupt_flag == HIGH)
{
delay(7000);
interrupt_flag = LOW;
}
Serial.println("AT+HTTPACTION=1"); /* Start POST session */
delay(3000);
if(interrupt_flag == HIGH)
{
delay(7000);
interrupt_flag = LOW;
}
Serial.println("AT+HTTPREAD"); /* Read data from HTTP server */
delay(2000);
}
余下程序:
注意:硬件串行实现的接收和发送缓冲区大小为16个字节。这不足以处理正在接收的数据或发送我们想要的数据。我们需要将其增加到更大的大小,例如85字节。
这可以通过将指令#define SERIAL_BUFFER_SIZE 16更改为Energia IDE文件夹中HardwareSerial.cpp文件中的#define SERIAL_BUFFER_SIZE 85来完成。您可以从路径中找到HardwareSerial.cpp文件,如下所示:
D:\TI_Launchpad_MSP430G2\energia-1.6.10E18\hardware\energia\msp430\cores\msp430
在这里,我们在D驱动器中将Energia IDE解压缩到一个名为TI_Launchpad_MSP430G2的文件夹中。
如果未更改大小,则代码将无法正常工作。
注意: 您需要使用您正在使用的SIM卡的网络提供商的APN。
在代码中,使用了Tata Docomo的APN(TATA.DOCOMO.INTERNET)。
注意事项:上面给出的程序是为了概念的一般理解。它们不使用最佳方法来发送和接收命令和响应。
无论何时发送任何AT命令,都应在发送另一个命令之前检查其响应。
您可以参考AT Getga和PIC微控制器的HTTP Get和Post,了解如何发送命令,检查响应,然后采取适当的措施。