最近,我希望利用arduino实现基于互联网的通信,基于GPRS而不是WIFI等,场所受限制的通信方式,故我选择SIM800l这款小型的GSM/GPRS模块,该模块可以实现通过AT命令进行打电话,发短信,并且可以实现tcp连接,也可以基于GPRS的互联网的访问。本文实现的就是sim800l基于gprs技术的互联网访问。最终效果就是从某个服务器上获取特定格式的命令信息。
附效果图
完整程序:(延时真的非常重要,否则会存在无法获取数据的现象)
#include <SoftwareSerial.h>
#include <MsTimer2.h>
//SIM800 TX is connected to Arduino D8
#define SIM800_TX_PIN 8 //D8连接sim800l的tx
//SIM800 RX is connected to Arduino D9
#define SIM800_RX_PIN 9 //D9连接sim800l的rx
SoftwareSerial mySerial(SIM800_TX_PIN,SIM800_RX_PIN);//定义虚拟串口
void setup(){
delay(10000);//单片机和sim800l上电之后,这个延时是用来等待sim800l获取信号(获取到信号之后的状态是3s闪一下)
Serial.begin(9600);//初始化默认串口
SIM800Init();//初始化sim800l,并将其置于数据连接打开的状态
bitSet(DDRB,5);//位操作,将D5口置高
MsTimer2::set(1000,getData_ISR);//定时器中断1s一次,即每两秒获取一次数据
MsTimer2::start();//开启定时器
}
char cmd[10]={0};//获取到的数据,长度为10个char
char sign=0;//步骤标志位,这样可以少加一个定时器
void loop(){//循环函数
delay(500);
char i=0;
for(i=0;i<=9;i++)Serial.write(cmd[i]);//输出获取到的数据
if(cmd[0]=='1'){
Serial.println("TURE");//如果第一位为’1‘即认定
if(cmd[1]=='1')bitSet(PINB,5);//如果第二位为’1‘即认定执行翻转电平的操作
}else{
Serial.println("FALSE");//否则数据无效
}
}
void SIM800Init(){
mySerial.begin(9600);//初始化串口波特率
delay(1000);//适当延时
Serial.println("Setup Complete!");
mySerial.write("AT\r");//发送AT返回OK
while(mySerial.available())Serial.write(mySerial.read());//接收返回的数据并打印到串口监视器上
mySerial.write("AT+SAPBR=3,1,\"APN\",\"CMNET\"\r");//注册
delay(500);
while(mySerial.available())Serial.write(mySerial.read());
mySerial.write("AT+SAPBR=3,1,\"PHONENUM\",\"15100000000\"\r");//注册
delay(500);
while(mySerial.available())Serial.write(mySerial.read());
mySerial.write("AT+SAPBR=4,1\r");
delay(500);
while(mySerial.available())Serial.write(mySerial.read());
mySerial.write("AT+SAPBR=1,1\r");//打开承载此时sim800l上的灯快闪
delay(1000);
while(mySerial.available())Serial.write(mySerial.read());
mySerial.write("AT+SAPBR=2,1\r");
delay(1000);
while(mySerial.available())Serial.write(mySerial.read());
mySerial.write("AT+HTTPINIT\r");//初始化http协议
delay(1000);
while(mySerial.available())Serial.write(mySerial.read());
mySerial.write("AT+HTTPPARA=\"CID\",\"1\"\r");
delay(500);
while(mySerial.available())Serial.write(mySerial.read());
mySerial.write("AT+HTTPPARA=\"URL\",\"http://test.umview.com/\"\r");//连接到服务器
delay(500);
while(mySerial.available())Serial.write(mySerial.read());
mySerial.write("AT+HTTPACTION=0\r");//请求
delay(1000);
while(mySerial.available())mySerial.read();//此时请求成功的话会获取到’0,200,20‘200是服务器的返回码代表请求成功,获取到的长度
mySerial.write("AT+HTTPREAD=1,14\r");//开始获取长度为14
delay(1000);
while(mySerial.available())Serial.write(mySerial.read());//串口输出
}
void getData(){//获取数据函数
char cnt=0;
while(mySerial.available()){
char c=mySerial.read();
if(c=='#'){//识别’#‘
for(cnt=0;cnt<=9;cnt++)cmd[cnt]=mySerial.read();//保存数据到cmd数组,并识别到’#‘为结束
}
mySerial.read();//读取剩下的字符
}
}
void requestDataStep1(){
mySerial.write("AT+HTTPACTION=0\r");//请求数据
}
void requestDataStep2(){
while(mySerial.available())mySerial.read();
mySerial.write("AT+HTTPREAD=1,14\r");//请求特定字长的数据
}
void getData_ISR(){ //定时器中断,1s执行一次
if(sign==0)requestDataStep1(),sign++;//第一步执行 requestDataStep1
else if(sign==1)requestDataStep2(),sign++;//第二步执行 requestDataStep2
else getData(),sign=0,Serial.println("getData");//第三步执行 getData 获取数据
}
服务器上的数据格式是:##1101012345#
注:第一个#无法获取到,有效数据为#之间的部分,’1‘为数据有效标志位。
至此,我们成功利用arduino通过sim800l基于gprs获取到互联网上的数据,并成功控制了一个LED。
优点:利用中断节约了大量cpu时间,这些时间本该用于延时获取数据时的等待。基于移动互联网,不过多地受位置限制,有移动信号就可以。
缺点:此sim800l模块,对电压要求较高,低电压会报警重启。对于串口的缓存区,必须要即时清空,否则会影响有效数据的接收,出现乱码,设置有效位’1‘可能会解决此类问题,可能需要设置很多有效位。由于存在较多的while用于清空串口的buff,存在程序卡死在while中的现象,但不多。通电时间长了,sim800l会存在轻微发热的情况。还有服务器上的数据第一个字节无法获取,问题无法解决。
可是,对于用sim800l上传数据和连接tcp服务器的功能并没有开发出来,需要日后继续改进。
附源代码:https://github.com/umview/Arduino
除非注明,嗯VIEW文章均为原创,转载请以链接形式标明本文地址
本文地址:https://www.umview.com/arduino-with-sim800l-get-data-via-GPRS
您好,请问这里可以用4G的电话卡吗?
可以
您好,我按照你的代码,执行后9600串口上一直显示FALSE和getDate为什么呢?
可能是因为,请求服务器数据失败了,或者是传输错码了,建议换个网站!
用SoftwareSerial连接SIM800这方法好,留着标准serial做串口监视用。一接上TX,RX,V-ref, GND就行了,可发AT命令了。
用标准口的话以后还是要折腾,不如留着调试用。哈。
大神,本人做移动端软件开发,没接触过硬件,有问题请教,请加我微信:wuxian,有谢!
求连线,arduino UNO 和SIM800C,QQ1564346140事后有心意,谢谢
大佬,,我已经加过你了:)
求教,我也不会怎么连线,SIM800和uno r3,谢谢,QQ769814089,事成有心意
本人小白,想要给我外婆弄个报警器,可以第一时间让子女知道,我买了arduino 101 和sim800,可是后来我蒙蔽了,不知道怎么连线,!!~~~~
大神,求帮助。
本人之前就是个普通的程序员,没接触过硬件
私聊一下吧。
我也刚买了个SIM800,同样不懂连线,模块也没相关资料,同求帮助
您好,我看你用的也是SIM800,您的代码好用了吗?