برنامه این پروژه به سه بخش اصلی تقسیم میشود که این سه بخش عبارتند از دریافت تماس از کاربر ، دریافت جهتهای جغرافیایی GPS از SIM800 و ارسال دادههای GPS به گیرنده تماس از طریق ارسال پیامک
بدست آوردن طول و عرض جغرافیایی از ماژول GSM SIM800
از AT command هایی که در جدول بالا مشخص شده است، به منظور دریافت اطلاعات موقعیت در فرمت DD از ماژول SIM800 استفاده میشود.
نکته: قبل از انجام مراحل فوق مطمئن شوید كه سیم کارت از شبکه 2G و GPRS پشتیبانی میكند.
در صورت اجرای دستورات فوق چیزی مانند تصویری که در بالا مشاهده میکنید، در سریال مانیتور آردوینو دیده میشود.
در تصویر بالا و قعیت نهایی در کادر قرمز مشخص شده است. همانطور که می بینید پاسخ برای دستور "AT + CIPGSMLOC = 1،1" چیزی شبیه به این خواهد بود:
+CIPGSMLOC: 0,75.802460,26.848892,2019/04/23,08:32:35
عدد 0 نشان دهندهی پین کد مکان، 26.8488832 عرض و 75.802460 طول جغرافیایی است. بنابراین از این مقادیر باید مکان مورد نظر را خارج کرده و آن را به یک لینک Google Map اضافه کنیم تا مکان و آدرس آن روی نقشه مشخص شود. لینک به صورت زیر خواهد بود:
https://www.google.com/maps/place/26.8488892,75.802460
برای انجام این کار از یک برنامه آردوینو نیز استفاده خواهیم کرد و در صورت درخواست لینک را به عنوان پیامک به تلفن مورد نظر ارسال میکنیم. سورس کد کامل و ویدئو در انتهای آموزش قرار داده شده است.
آردوینو با ماژول SIM800 ارتباط سریال برقرار کرده و از طریق AT Command ها فرمان میگیرد. با ارسال هر AT Command، ماژول با ارسال کاراکتر پاسخ داده و اگر نتیجه موفقیت آمیز باشد با پیام OK خاتمه مییابد.
بنابراین قبل از شروع برنامه ، تابعی به نام SIM800_send را می نویسیم که Command AT را به صورت یک رشته دریافت کرده و با استفاده از SIM800 آن را به ماژول GSM منتقل کند. تابع ()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 function میزان بودریت ماژول و کامپایلر را 9600 قرار میدهیم. همچنین پین 12(PWR_KY) برای 1 ثانیه low کرده تا ماژول GSM را فعال کنیم. ابتدا حالت echo را با استفاده از دستور "ATE1" فعال کرده و سپس دستورات ذکر شده در بالا را دنبال میکنیم تا هماهنگی های لازم را از ماژول GSM بدست آوریم. در حالت echo به ازای ارسال هر کاراکتر ماژول دقیقا همان کاراکتر را بر میگرداند. پس از ارسال هر AT command ، به منظور اشکال زدایی پاسخ را در سریال مانیتور کامپایلر نشان میدهیم.
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+CIPGSMLOC که در واقع مختصات مکان را میدهد استفاده نشده است. به این دلیل که قرار است از این دستور فقط هنگام تماس با ماژول GSM استفاده شود. در داخل حلقه اصلی، بررسی میشود که آیا ماژول درخواستی ارسال کرده است یا خیر. در صورت دریافت تماس از جانب ماژول پیغام "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 */
/* { */
در صورت دریافت تماس باید دادههای مربوط به تشخیص موقعیت واکشی شده و به یک لینک google map تبدیل شده و در نهایت به عنوان یک پیامک ارسال شوند. قبل از آن لازم است تماس ورودی قطع شود. برای این کار از دستور "ATH " استفاده میشود. سپس حالت echo را با استفاده از ATE0 غیرفعال کرده و دستور "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
مجددا از همان تکینکی که در حلقه اصلی استفاده شد برای تبدیل کاراکترهای خروجی به رشته استفاده میشود. رشته پاسخ دستور AT + CIPGSMLOC = 1،1 خواهد بود که شامل طول و عرض جغرافیایی است. برای مرتب کردن و نمایش این مقادیر از تابع ()prepare_message استفاده میشود.
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);
حال که مقدار طول و عرض جغرافیایی بدست آمده است، باید آن را با دستور زیر به فرمت یک لینک تبدیل کرد. در آخر لینک به صورت پیامک به شماره تلفن همراه مورد نظر ارسال میشود. شماره تلفن همراه توسط دستور"AT + CMGS = +98912xxxxxxx" ثبت میشود. در این دستور شماره تلفن مورد نظر خود جایگزین کنید.
SIM800.println("AT+CMGF=1"); //Set the module in SMS mode
delay(1000);
SIM800.println("AT+CMGS="+98912xxxxxxx ""); //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);