忙了一个多月,终于完成了一套系统的开发,笔者参与完成了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();
}
}
}
笔者实验发现,都很成功