arduino: sim900+GPS Shield

【教程】sim900+GPS Shield短信查询定位 

[复制链接]
0
   

allowtransparency="true" scrolling="no" border="0" width="120" height="24" frameborder="0" src="http://widget.weibo.com/relationship/followbutton.php?language=zh_cn&width=136&height=24&uid=2917365934&style=2&btn=light&dpc=1" style="word-wrap: break-word;">

该用户从未签到

参加活动: 

组织活动: 

跳转到指定楼层
楼主
  发表于 2014-7-31 17:02:17  |  只看该作者  | 只看大图  回帖奖励
本帖最后由 ITEAD创易工作室 于 2014-8-19 09:30 编辑

Hi,很高兴又跟大家见面了。之前给大家介绍了ICOMSAT,一款能打电话,收发短信的sim900扩展板。请注意,是扩展板!那么它肯定可以再直接叠加其他扩展板咯!没错,今天我们就给它加上定位跟踪功能。  GPS shield是一款可以实现全球定位的扩展板,把它们结合在一起,我们就可以轻松地实现利用短信来查询当前的位置坐标,可以应用于货物定位查询。
需要用到的配件有:

 
等等!Iteaduino MEGA2560这个是什么鸟板?为什么不可以用UNO或者mega2560标准版?!你这是红果果地在打广告啊!举报版主!

版主别开枪!请听我编故事:

从前有个独臂神医,叫UNO,每天都要用净瓶收集清晨的露水用来制作药丹,医治贫苦众生。但他只有一只手,一个瓶,每天在太阳升起的时候才收集到很少。此事感动了上苍,造物主一次给他加了3只手,他现在一共有了4只手, 所以他可以用更多的瓶子接到更多的露水了。这样的故事看似应该收尾了,但是他发现虽然比以前接得多了,但是造物主开了个玩笑,给他的三只手都在同一个地方,还是在背后。3只手接同一边的露水,一只手接另一边的露水,往往单手的这边接满了,3只手的这边露水也早就接没了,每个只有半瓶多,这是极大的浪费。后来一位手术整形师听闻了此事,特地给他做了移植手术,把背后的三只手,其中一只手装到了单手的这边,另外两只装在对称的另一边。这样不仅美观帅气,还能灵活使用4只手协调工作了。他现在就是Iteaduino MEGA2560。详细产品资料http://pan.baidu.com/s/1o6uPI7g

故事编完了,继续今天的教程。

硬件设置和搭建:

a)Icomsat 的开关拨到UART的一端,跳线帽按照RXD->D2,TXD->D3如图,接上GSM天线和插上手机SIM卡。详细跳帽和引脚请下载查阅产品手册和原理图: http://pan.baidu.com/s/1eQGezWu   

 
b)GPS 扩展板的开关拨到5V,跳线帽按照RXD->D1,TXD->D0如图连接,接上GPS天线。详细产品资料下载: http://pan.baidu.com/s/1i3kk9FZ
 

c)  我们的程序中会使用到MEGA2560的两个串口,UART1连接到Icomsat,UART2连接到GPS shield, 另外还有多余的串口可以烧写程序,所以可以先叠加好3个板子,连接USB线,直接烧写固件。

把mega2560的开关拨到5V的一边。(此板还可以提供3.3v的IO电平)

再把GPS shield和Icomsat堆叠起来,然后插到MEGA board板子上一排Arduino socket上
 

 

 

d ) 连接完成后的硬件图如下所示:
 

烧写程序:

a) 首先我们需要下载GSM和GPS的Arduino支持库。



b)  把两个库解压缩到Arduino\libraries的目录下,然后打开arduino IDE.
接着把代码复制黏贴到Arduino IDE,烧写到MEGA主板上。“Board板子类型选择mega2560 or ADK”

[C]  纯文本查看  复制代码
?
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
#include "SIM900.h"
#include <SoftwareSerial.h>
//#include "inetGSM.h"
#include "sms.h"
//#include "call.h"
 
#include <string.h>
 
#include <TinyGPS.h>
 
/* This sample code demonstrates the normal use of a TinyGPS object.
    It requires the use of SoftwareSerial, and assumes that you have a
    4800-baud serial GPS device hooked up on pins 3(rx) and 4(tx).
*/
 
TinyGPS gps;
 
#define ledpin 13
#define pwrkey 27
 
//**************************************************************************
char sms_rx[122]; //Received text SMS
byte type_sms=SMS_ALL;      //Type of SMS
byte del_sms=1;                //0: No deleting sms - 1: Deleting SMS
char number_incoming[20];
//**************************************************************************
SMSGSM sms;
int error;
boolean started= false ;
bool newData = false ;
 
char gps_year[8];
char gps_mon[3];
char gps_day[3];
char gps_hour[3];
char gps_min[3];
char gps_sec[3];
 
 
char gps_lon[20];
char gps_lat[20];
 
char gps_sms[100];
 
 
void setup()
{
 
//software power sim900 up
 
   pinMode(pwrkey,OUTPUT);
   digitalWrite(pwrkey,HIGH);
   delay(600);
   digitalWrite(pwrkey,LOW);
   
   
   Serial.begin(115200);
   Serial2.begin(9600);
      if (gsm.begin(9600)) {
           Serial.println( "\nstatus=READY" );
           gsm.forceON();        //To ensure that SIM908 is not only in charge mode
           started= true ;
      } else Serial.println( "\nstatus=IDLE" );
 
   if (started)
   {
         //delete all sms message
         
         Serial.println( "Deleting SMS" );
         char error = DeleteAllSMS();
         if (error==1)Serial.println( "All SMS deleted" );     
     else Serial.println( "SMS not deleted" );
 
   
   }
   else
   {Serial.println( "SIM900 NOT EXISTED" ); while (1);}
   delay(10000);
   
}
 
void loop()
{
 
         if (started)
         {
         
                 check_gps();
                 Check_SMS();
         
         }
 
 
 
 
 
}
 
 
 
  void Check_SMS()  //Check if there is an sms 'type_sms'
  {
      char pos_sms_rx;  //Received SMS position    
      pos_sms_rx=sms.IsSMSPresent(type_sms);
      if (pos_sms_rx!=0)
      {
        //Read text/number/position of sms
        sms.GetSMS(pos_sms_rx,number_incoming,sms_rx,120);
        Serial.print( "Received SMS from " );
        Serial.print(number_incoming);
        Serial.print( "(sim position: " );
        Serial.print(word(pos_sms_rx));
        Serial.println( ")" );
        Serial.println(sms_rx);
        if (del_sms==1)  //If 'del_sms' is 1, i delete sms
        {
          error=sms.DeleteSMS(pos_sms_rx);
          if (error==1)Serial.println( "SMS deleted" );     
          else Serial.println( "SMS not deleted" );
 
        }
                 if (( strstr (sms_rx, "gps" )!=0)&&( strlen (sms_rx)==3))
                 {
                                         Serial.println( "\nsending SMS" );
                                 if (newData)
                                 {
                                         if (sms.SendSMS(number_incoming, gps_sms))
                                         Serial.println( "\nSMS sent OK" );
                                         else
                                         Serial.println( "\nSMS sent error" );       
                                 }
                                 else
                                 {
                                         if (sms.SendSMS(number_incoming, "gps not ready" ))
                                         Serial.println( "\nSMS sent OK" );
                                         else
                                         Serial.println( "\nSMS sent error" );                                               
                                 }
                                 
                 }
         Serial2.flush();
                 
      }
          newData= false ;
      return ;
  }
  
  
char check_gps()
{
   newData= false ;
   unsigned long chars;
   unsigned short sentences, failed;
 
   // For one second we parse GPS data and report some key values
   for (unsigned long start = millis(); millis() - start < 1000;)
   {
     while (Serial2.available())
     {
       char c = Serial2.read();
       // Serial.write(c); // uncomment this line if you want to see the GPS data flowing
       if (gps.encode(c)) // Did a new valid sentence come in?
         newData = true ;
     }
   }
 
   if (newData)
   {
     float flat, flon;
     unsigned long age;
     int _year;
     byte _month, _day,_hour,_minute,_second,_hundredths;       
     gps.f_get_position(&flat, &flon, &age);
         gps.crack_datetime(&_year,&_month,&_day,&_hour,&_minute,&_second,&_hundredths,&age);
         flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6;
         flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6;
     dtostrf(flat, 11, 6, gps_lat);
     dtostrf(flon, 10, 6, gps_lon);
         
         strcpy (gps_sms, "lat:" );
         strcat (gps_sms,gps_lat);
         strcat (gps_sms, "\n" );
         strcat (gps_sms, "lon:" );
         strcat (gps_sms,gps_lon);
         strcat (gps_sms, "\n" );
         strcat (gps_sms, "time:" );
         
     itoa(_year,gps_year,10);
     strcat (gps_sms,gps_year);
         
     itoa(_month,gps_mon,10);
     if ( strlen (gps_mon)==1)
       strcat (gps_sms, "0" );
     strcat (gps_sms,gps_mon);
         
     itoa(_day,gps_day,10);
         if ( strlen (gps_day)==1)
       strcat (gps_sms, "0" );
     strcat (gps_sms,gps_day);
         
     itoa(_hour,gps_hour,10);
         if ( strlen (gps_hour)==1)
       strcat (gps_sms, "0" );
     strcat (gps_sms,gps_hour);
         
     itoa(_minute,gps_min,10);
         if ( strlen (gps_min)==1)
       strcat (gps_sms, "0" );
     strcat (gps_sms,gps_min);
         
     itoa(_second,gps_sec,10);
         if ( strlen (gps_sec)==1)
       strcat (gps_sms, "0" );
     strcat (gps_sms,gps_sec);       
         
     Serial.println(gps_sms);
 
 
   }
   
 
 
 
}
  
char DeleteAllSMS()
{
      char ret_val = -1;
 
 
      if (CLS_FREE != gsm.GetCommLineStatus()) return (ret_val);
      gsm.SetCommLineStatus(CLS_ATCMD);
      ret_val = 0; // still not present
          
      gsm.SimpleWriteln(F( "AT+CMGDA=\"DEL ALL\"" ));
          
      switch (gsm.WaitResp(8000, 50, "OK" )) {
      case RX_TMOUT_ERR:
           // response was not received in specific time
           ret_val = -2;
           break ;
 
      case RX_FINISHED_STR_RECV:
           // OK was received => SMS deleted
           ret_val = 1;
           break ;
 
      case RX_FINISHED_STR_NOT_RECV:
           // other response: e.g. ERROR => SMS was not deleted
           ret_val = 0;
           break ;
      }
 
      gsm.SetCommLineStatus(CLS_FREE);
      return (ret_val);        
}


拔掉USB线,改用9V/2A外部电源供电,GPS的天线尽量放到信号好的高处。等Icomsat开机一段时间后,用手机给sim卡发送一条“gps”的短信,稍后,你会收到一条返回短信。里面包含了经度纬度以及时间信息,例如:

lat:22.588160
lon:113.944100
time:20140730073230
lat 表示纬度,lon表示经度,time表示标准的“格林尼治时间”( 本初子午线 ),跟北京时间相差8个小时。

如果你收到一条“gps not ready”的短信,表示GPS shield还没定位好。等待连接卫星信号的时间跟天气、地区、环境等因素有关,长则几分钟,短则几十秒。
  



上一篇:arduino与mpu6050连接
下一篇:求助关于蓝牙连接小车
制作一个基于arduino 和12864液晶模块的图形化显示GPS导航系统,作品效果和成本可能无法和TB上的导航产品媲美,但是动手过程会带给你乐趣和知识。 需要了解的背景知识: arduino 相关基础; 能使用12864 液晶模块; 能够用arduino 通过串口通信获取GPS模块定位信息; 能够用arduino 操作SD卡模块; 需要的主要硬件: arduino UNO 1片; 12864 液晶模块 1片; GPS模块1片; SD卡模块及SD卡 1套; 原理介绍: 将地图数据依据瓦片算法存储在SD卡中,通过串口获取GPS定位信息并从中解析出经纬度坐标,依据经纬度坐标读取相应地图数据显示在12864液晶模块上,同时显示定位坐标点。 1. 地图存储算法——瓦片系统(Maps Tile System) 本制作采用的地图数据和地图存储算法来源于微软的bing maps并做了相应修改,具体可参考: Bing Maps Tile System[1*] Virtual Earth Tile Image URI 参数解析 Goolge and Microsoft Map Url Parameters 在瓦片系统中地图采用金字塔式的分层存储结构,不同层具有不同级别的地图分辨率(地图精细程度),每一层地图被分割成等像素大小(256X256)的瓦片,算法要解决的问题就是给定经纬度坐标和缩放级别(层索引)得到具体相应的瓦片编号。 在连接[1*]的最后有算法实现的代码可共参考。 2. 针对12864液晶模块的设计 12864液晶模块是128像素宽64像素高的单色液晶显示模块,本制作为了适应模块显示做出了两个设计。 1). 将256X256像素的瓦片裁切成128X64像素大小的8份 子瓦片,如下图所示: 每层每个瓦片均做相应处理。 2). 通过阈值方法将8位png索引图像(bing maps 的道路数据)转换成二进制地图数据文件,为了能够显示原图中的文字信息,采用多阈值提取求或方法提取原地图中背景、地物和标注文字数据,由于标注文字和背景之间的扰动,提取效果有待改进。 显示效果: 生成地图程序(需要连接互联网): 通过设置地图范围经纬度信息获取要使用定位的区域,可通过google earth 等能显示经纬度的软件或网页获取经纬度的最大最小值(上大下小,右大左小), 缩放级别建议设置范围1~15,较大地图范围和较高缩放级别会增加地图下载、显示加载的时间。 arduino 代码说明: 1. 在“LCD12864RSPI” 文件中加入画点函数,减少重绘区域; 2. 使用占用内存小、具有只读能力的SD模块库“petit_fatfs”; 3. 分配1K内存用于地图数据缓存,由于SD卡库只支持8.3文件名,地图数据文件名采用十六进制不定长压缩编码方式命名。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值