| 自动驾驶汽车和联网汽车肯定会改变我们未来的通勤方式。如今,像特斯拉这样的公司正在鼓励其汽车所有者在没有使用汽车时借出他们的汽车,用作自动驾驶出租车。最近特斯拉首席执行官埃隆·马斯克(Elon Musk)发表了一篇推特,提到2020年将有超过100万台自动驾驶出租车上路。这不仅仅是影响一般运输,也改变了现今物流的运作方式。 
 由于自动驾驶汽车载有乘客,卡车载有贵重货物,因此需要一个车队管理系统,我们需要跟踪它们以了解其位置并确保它们是否在正确的时间出现在正确的位置。通常,GPS模块用于任何类型的位置跟踪,但在本文中,我们将使用GSM SIM800模块和Arduino开发板制作一个简单的位置跟踪系统。这种GPRS跟踪系统涉及GSM调制解调器和微控制器(Arduino)。它的工作过程如下:当向GSM模块打电话时,模块将检查位置并将其作为短信发回进行电话呼叫的号码,该短信中包含谷歌地图链接。在手机上打开此链接会将调制解调器的位置固定显示在Google地图上。听起来很有意思!!那么,让我们开始吧。 
 电路原理图 该GSM位置跟踪系统将使用SIM800 GSM模块的GPRS功能,模块将与Arduino等微控制器连接。虽然GSM模块和Arduino开发板都是单独的包装,但我决定将自己的电路组合在一块板上以节省成本和空间。该电路板可以通过12V适配器或汽车/卡车中的12V电池供电,板载降压转换器将12V降压至4V用于GSM模块,以及降压至3.3V的微控制器工作。完整的电路图如下。 
  
 
  
 在下面我将把这个电路图分成块并解释它们以确保你可以使用它们或根据你的应用需求修改它们。 
 LM2596电源模块 我们使用LM2596降压稳压器IC从输入12V降压至4V,为SIM800模块提供电源。 SIM800模块在初始化和搜索网络时需要大约2A的峰值电流,因此电源应该能够提供该电流,否则模块将进入关断模式,因此选择可提供高达3A的LM2596。电源调节器电路如下所示。 
  
 将12V未调节电压提供给引脚1,在引脚2上获得稳压电压,然后将其分别通过值为100uH和470uF的LC滤波器,以滤除输出开关噪声。输出电压可以通过使用形成分压电路的电阻R30和R29来设置,并连接到反馈引脚,如上所示。计算LM2596输出电压的公式如下 Vout = 1.23 *((R1 + R2)/ R1) 在我们的上图中,R29是R1,R30是R2。因此,我为R29选择了1k的值,为R30选择了2.2k的值,以获得4V的输出电压。请注意,SIM800模块需要在3.7V至4.2V之间重新获得电压才能正常工作。 
 使用SIM800 IC供电和通信 SIM800 GSM调制解调器通常作为模块使用,但我们使用裸IC封装来减少电路板空间和成本。使用SIM800调制解调器非常简单,只需通过VBAT和GND引脚为IC供电,然后使用PWR KEY引脚通过将引脚向下拉1秒来启用调制解调器。默认情况下,引脚通过电阻在内部拉高至VBAT。 
  
 VBAT的电压来自LM2596 IC的稳压电压(GSM_VCC)。该引脚名为VBAT,因为它通常由锂电池供电,因此如果您在便携式设备上使用它,那么您可以跳过LM2596电路并将其直接连接到锂聚合物电池。然后我们将网络引脚连接到6针SIM卡卡槽,以连接我们的SIM卡。 NETLIGHT引脚连接到LED,该LED将作为状态LED指示网络状态,尽管它是可选的。类似地,BT_ANT引脚可用于将模块连接到天线以轻松找到网络连接,这也是可选的。 
 最后,我们将TxD和RxD引脚拉出到引脚引脚,这两个引脚将用于通过标准USART协议以9600波特率与Arduino等微控制器通信。上面电路中显示的其他连接是可选的,对此项目没有任何重要意义。 
 GSM定位器的微控制器侧 在微控制器方面,我们采用ATMEGA328P芯片,这是Arduino UNO / Nano中使用的芯片,但这里控制器直接嵌入在电路板上与SIM800模块通信。 由于SIM800模块采用3.3V逻辑工作,因此我决定采用3.3V本身运行ATmega328芯片,因为它还支持3.3V和5V工作电压。 
  
 因此,如上所示,我使用AMS1117 3.3V稳压器IC从输入12V调节3.3V电压,并用它为Atmega328 IC供电。 虽然SIM800可在3.3V逻辑电平下工作,但它也可以在外部与Arduino Nano / Uno进行通信,而无需任何逻辑电平转换器。 该电路还通过插头引出一些引脚,以帮助我们使用外部FTDI编程器对Atmega328 IC进行编程,类似于我们在3.3V模式下使用Arduino Pro mini。 
 将电路板连接到Arduino Nano开发板 标记为P2的电路板上的外部插头可以直接连接到Arduino Nan。在这里,我根据下表连接了引脚 |  Arduino Nano |  SIM800 |  | D12 | PWR_KY |  | D11 | TxD |  | D10 | RxD |  | GND | GND | 
 连接到引脚D12的电源键用于在上电后启用/禁用模块,这有助于在不使用模块时节省电量。引脚D11和D12分别连接到Tx和Rx引脚,我们将Arduino编程为使用这些引脚作为软件串行与板通信。一旦建立连接,设置如下所示。 
  
 用于GPRS车辆跟踪系统的Arduino编程 整个项目可以分为三个主要部分,例如接收用户的呼叫,从SIM800获取GPS坐标,通过SMS将GPS数据发送给呼叫者。 
 从SIM800 GSM模块获取地理坐标位置(纬度和经度):与GSM相比,从GPS获得GPS坐标很容易。 
 直接通过串行通信执行的命令将如下所示响应
 
  
 我在上面的图片中圈出了最终的位置结果。正如您所看到的,命令“AT + CIPGSMLOC = 1,1”的响应将是这样的 复制代码+CIPGSMLOC: 0,75.802460,26.848892,2019/04/23,08:32:35
其中0是位置Pin码,26.8488832是纬度,75.802460是经度。因此,我们必须从此结果中抽取这些值,并将其附加到Google地图链接,以将地点和地址指向地图。链接将是这样的: https://www.google.com/maps/place/26.8488892,75.802460 
 我们将使用我们的Arduino代码执行此操作,并在需要时将链接作为短信发送到我们的手机。 
 Arduino通过与AT命令的串行通信与SIM800模块通信。对于我们发送的每个AT命令,模块将在字符后回复字符,如果结果成功,则消息将以OK结束。因此,在开始我们的程序之前,我们编写一个名为SIM800_send的函数,它将AT命令作为字符串并使用SIM800传递给GSM模块。 println命令然后使用SIM800.read()函数从SIM800模块返回结果并将其返回。功能如下所示 复制代码String SIM800_send(String incoming) //Function to communicate with SIM800 module
{
    SIM800.println(incoming); delay(100); //Print what is being sent to GSM module
    String result = "";
    while (SIM800.available()) //Wait for result
    {
    char letter = SIM800.read();
    result = result + String(letter); //combine char to string to get result
    }
return result; //return the result
}
 在setup()函数中,我们初始化串口监视器和SIM800通信以及9600波特率,并使引脚12(PWR_KY)保持低电平1秒以启用GSM模块。然后我们使用上面创建的函数与GSM模块通信。我们首先使用“ATE1”启用回声,然后开始按照上面列出的命令从GSM模块获得坐标。在每个AT命令之后,我们在串行监视器上打印响应以进行调试,下面给出了相同的代码: 复制代码void setup() {
//PWRKY pin of GSM module has to be pulled low for 1sec to enable the module
  pinMode(12,OUTPUT);
  digitalWrite(12, LOW);   //Pull-down
  delay(1000);                     
  digitalWrite(12, HIGH); //Release
  Serial.begin(9600); //Serial COM for debugging
  SIM800.begin(9600); //Software serial called SIM800 to speak with SIM800 Module
  delay(1000); //wait for serial COM to get ready
  responce = SIM800_send("ATE1"); //Enable Echo if not enabled by default
  Serial.print ("Responce:"); Serial.println(responce);
  delay(1000);
  responce = SIM800_send("AT+CGATT=1"); //Set the SIM800 in GPRS mode
  Serial.print ("Responce:"); Serial.println(responce);
  delay(1000);
  responce = SIM800_send("AT+SAPBR=3,1,"CONTYPE","GPRS" "); //Activate Bearer profile
  Serial.print ("Responce:"); Serial.println(responce);
  delay(1000);
  responce = SIM800_send("AT+SAPBR=3,1,"APN","RCMNET" "); //Set VPN options => 'RCMNET' 'www'
  Serial.print ("Responce:"); Serial.println(responce);
  delay(2000);
  responce = SIM800_send("AT+SAPBR=1,1"); //Open bearer Profile
  Serial.print ("Responce:"); Serial.println(responce); //Open bearer Profile
  delay(2000);
  responce = SIM800_send("AT+SAPBR=2,1"); //Get the IP address of the bearer profile
  Serial.print ("Responce:"); Serial.println(responce);
  delay(1000);
}
 请注意,我们没有使用列表中的最后一个AT命令来实际获取位置坐标。这是因为我们将仅在向GSM模块发出呼叫时使用它们。 
 在loop函数内部,我们检查模块是否在接收到呼叫。如果模块接到呼叫,它将打印出“RING”。因此,我们制定了程序以检查RING购买将所有输出字符串联到字符串并将其直接与“RING”进行比较。相同的代码如下所示。 复制代码  if (SIM800.available()) { //Check if the SIM800 Module is telling anything
    char a = SIM800.read();
    Serial.write(a); //print what the module tells on serial monitor
    incoming = incoming + String(a);
    if (a == 13) //check for new line
    incoming =""; //clear the string if new line is detected
    incoming.trim(); //Remove /n or /r from the incomind data
    if (incoming=="RING") //If an incoming call is detected the SIM800 module will say "RING" check for it
    {
 如果检测到RING,则需要获取位置数据,裁剪数据并将其转换为谷歌地图链接,最后将其作为短信发送。但在此之前我们需要挂断来电,为此我们使用命令“ATH”。然后我们使用ATE0禁用echo并使用“AT + CIPGSMLOC = 1,1”命令从互联网获取位置数据。 复制代码     Serial.println ("Sending sms"); delay(1000);
     responce = SIM800_send("ATH"); //Hand up the incoming call using ATH
     delay (1000);
     responce = SIM800_send("ATE0"); //Disable Echo
     delay (1000);
     responce = ""; Latitude=""; Longitude=""; //initialise all string to null
     SIM800.println("AT+CIPGSMLOC=1,1"); delay(5000); //Request for location data
 同样,我们使用相同的while循环将输出字符转换为字符串。这次字符串将具有AT + CIPGSMLOC = 1,1命令的响应,该命令将包含我们已经讨论过的纬度和经度信息。我们将使用prepare_message()函数来修剪纬度和经度的值。正如您在下面的示例消息中看到的那样 复制代码+CIPGSMLOC: 0,75.802460,26.848892,2019/04/23,08:32:35
 经度值后跟第一个命令,第二个命令结束。类似地,纬度的值以第二个命令开始,以第三个逗号结束。我们可以利用这些特征从程序中获取纬度和经度值。使用以下代码 复制代码void prepare_message()
{
  //Sample Output for AT+CIPGSMLOC=1,1   ==> +CIPGSMLOC: 0,75.802460,26.848892,2019/04/23,08:32:35 //where 26.8488832 is Lattitude and 75.802460 is longitute
  int first_comma = responce.indexOf(','); //Find the position of 1st comma
  int second_comma = responce.indexOf(',', first_comma+1); //Find the position of 2nd comma
  int third_comma = responce.indexOf(',', second_comma+1); //Find the position of 3rd comma
  for(int i=first_comma+1; i<second_comma; i++) //Values form 1st comma to 2nd comma is Longitude
    Longitude = Longitude + responce.charAt(i);
  for(int i=second_comma+1; i<third_comma; i++) //Values form 2nd comma to 3rd comma is Latitude
    Latitude = Latitude + responce.charAt(i);
 现在我们有了纬度和经度值,我们只需将它附加到我们的链接上,并在其间插入逗号以形成Link。下面给出了相同的代码。 复制代码 Serial.println(Latitude); Serial.println(Longitude);
  Link = Link + Latitude + "," + Longitude; //Update the Link with latitude and Logitude values
 最后,我们可以将链接作为短信发送到手机号码。在这里,我使用命令AT + CMGS =“907923XXXX”对手机号码进行了硬编码,请确保将该命令替换为您的电话号码。 复制代码SIM800.println("AT+CMGF=1"); //Set the module in SMS mode
     delay(1000);
     SIM800.println("AT+CMGS="907923XXXX""); //Send SMS to this number
     delay(1000);
     SIM800.println(Link); // we have send the string in variable Link
     delay(1000);
     SIM800.println((char)26);// ASCII code of CTRL+Z - used to terminate the text message
     delay(1000);
 测试GPRS跟踪设备 按照讨论的方式建立连接,并将代码上传到Arduino Nano开发板。插入SIM卡并确保已建立网络信号。一种方法是通过监控GSM模块上的LED来实现这一点,该模块应每3秒钟闪烁一次。现在打开串行监视器,您应该在屏幕上看到以下消息: 
  
 这意味着您的GSM模块设置为获取坐标并准备接听来电。您只需拨打任意号码的GSM SIM号码,您就会注意到在几声响起后呼叫被挂起,您将收到一条消息,告知您在该程序中输入的号码。短信将包含Google地图链接,如下所示: 
  
 点击该链接,您的手机将自动转到Google地图,并使用红色符号在手机上绘制收到的位置。然后,您可以导航到该位置或获取该位置的地址。打开时的上述链接如下所示 
  
 
 如您所见,蓝点是我的手机GPS提取的位置,红色标记是我们的GSM模块给出的位置。正如预期的那样,它不如GPS准确,但它仍然适用于我们的应用程序,并且非常有效,因为相同的模块可用于接收呼叫和发送SMS。 
 希望你喜欢这个项目,并喜欢制作。如果您有任何问题,请在本帖下面回复。 
 代码 本文使用的完整代码如下:
 main.rar
(1.91 KB, 下载次数: 54) |