ساخت تلفن گویا با برد رزبری پای و ماژول SIM800L
محتویات
در این پروژه با استفاده از برد رزبری پای یک سیستم تلفن گویا (هوشمند) طراحی میکنیم که میتواند اطلاعات را به صورت خودکار از کاربر بگیرد. در این آموزش از ماژول GSM Sim800l استفاده میکنیم. در ادامه اتصالات مدار و برنامه نویسی به طور کامل توضیح داده میشود.
مدار ساخت تلفن گویا با SIM800L و رزبری پای
مدار تلفن گویا مبتنی بر رزبری پای بسیار ساده است و در زیر نشان داده شده است.
ماژول SIM800L با 3.7 ولت تا 4.2 ولت کار می کند (برای باتری لیتیوم پلیمر طراحی شده است). ولتاژ عملیاتی ایده آل حدود 4 ولت است. ما از مبدل LM2596 Buck برای تبدیل ورودی 12 ولت 2A از آداپتور به 4 ولت برای ماژول SIM800L استفاده کرده ایم. ما باید با استفاده از “دستورات AT” به ماژول SIM800L ارتباط برقرار کنیم. از دستورات AT می توان برای برقراری / دریافت تماس ، ارسال / خواندن پیام و… استفاده کرد. در این پروژه ، ما از پایتون و Raspberry Pi برای ارسال این دستورات AT به ماژول GSM SIM800L استفاده خواهیم کرد. برای انجام این کار ، ما از مبدل USB به TTL برای اتصال پایه Rx و TX ماژول SIM800L به پورت USB Raspberry Pi استفاده کرده ایم.
ماژول SIM800L از ورودی میکروفون از طریق پین های MIC + و MIC روی ماژول پشتیبانی می کند. پس از برقراری تماس ، هر ورودی صوتی که به این پایه ها داده می شود ، در تلفن گیرنده پخش می شود. با این حال ، این پین ها در واقع برای اتصال میکروفون هستند و در مورد ما ، ما باید صدای از پیش ضبط شده را از Raspberry پخش کنیم.
میتوانید اتصالات را در یک برد سوراخدار معمولی انجام دهید. توجه: سیستم تلفن گویا که در اینجا ایجاد می کنیم فقط به سخت افزار خارجی برای اجرای کد پایتون و تهیه خروجی صدا احتیاج دارد. سخت افزار خارجی این پروژه Raspberry Pi است اما برای این کار می توانید از رایانه نیز استفاده کنید.
مهم: LM2596 یک مبدل متغیر است ، بنابراین قبل از استفاده از آن اطمینان حاصل کنید که ولتاژ خروجی را با استفاده از trimpot on-bord روی 4V تنظیم کرده اید. هر چیزی بیش از 4.2 ولت می تواند ماژول SIM800L را به طور دائمی خراب کند.
برد را روشن کرده و سیم کارت را وارد کنید. مطمئن شوید که سیم کارت را در جهت درست قرار داده اید و آنتن به درستی نصب شده است. اگر همه کارها به درستی انجام شده باشد ، باید متوجه شوید که چراغ روی برد SIM800L هر 3 ثانیه یکبار چشمک می زند. این بدان معنی است که ماژول SIM800L با شبکه سیم کارت ما ارتباط برقرار کرده است.
قطعات مورد نیاز
- برد رزبری پای (2 یا 3 یا 4)
- SIM800L ماژول GSM
- کابل Aux
- ماژول مبدل باک LM2596
- مبدل USB به TTL
- آداپتور 12 ولت 2 آمپر
کد پایتون تماس و ارسال پیامک با ماژول SIM800L
کد کامل و فایل های صوتی مورد نیاز در فایل دانلودی انتهای صفحه قرار گرفته اند. در ادامه قسمت های مهم کد را بررسی میکنیم.
ما برنامه را با فراخوانی کردن کتابخانه های مورد نیاز شروع می کنیم. ما از بسته سریال برای فعال کردن ارتباط سریال بین Pi و SIM800L استفاده کرده ایم ، از بسته pygame برای پخش موسیقی استفاده می شود. هر سه بسته از قبل در سیستم عامل Buster نصب شده است ، بنابراین شما نیازی به نصب چیز جدید ندارید.
import serial # برای برقرار ارتباط سریال با GSM SIM800L import time import pygame #برای پخش موسیقی
def SIM800 (Command): این عملکرد برای ارسال دستور AT از رزبری پای به SIM800L و دریافت پاسخ برای آن دستور AT استفاده می شود. تمام دستورات AT ارسال شده به SIM800L باید با “\r\n” پایان یافته و با ASCII رمزگذاری شوند. این تابع تمام دستورات AT ما را با “\r\n” همراه می کند و قبل از ارسال به SIM800L ، آنها را در فرم ASCII رمزگذاری می کند. سپس پاسخ را نیز خوانده و مقادیر ASCII را رمزگشایی می کند تا بتوانیم از آنها در برنامه خود استفاده کنیم.
#ارتباط با ماژول و دریافت پاسخ def SIM800(command): AT_command = command + "\r\n" ser.write(str(AT_command).encode('ascii')) time.sleep(1) if ser.inWaiting() > 0: echo = ser.readline() #waste the echo response_byte = ser.readline() response_str = response_byte.decode('ascii') return (response_str) else: return ("ERROR")
def wait_for_SIM800 (): این عملکرد نیز بسیار شبیه عملکرد فوق است ، اما هیچ مقداری را به SIM800 نمی فرستد ، فقط منتظر است SIM800L با چیزی پاسخ دهد. وقتی پاسخی دریافت می کند در نتیجه آن را برمی گرداند.
#دریافت پیام های SIm800l def wait_for_SIM800(): echo = ser.readline() # waste the echo response_byte = ser.readline() response_str = response_byte.decode('ascii') return (response_str)
def Init_GSM (): عملکرد ماژول GSM را برای عملیات تلفن گویا آماده می کند. ابتدا با ارسال “AT” و انتظار برای “OK” ماژول را بررسی می کند و سپس برخی دستورات AT خاص را برای قرار دادن ماژول GSM در حالت پیامرسانی و حالت گیرنده DTMF می فرستد. همچنین همه اعلان ها را نیز غیرفعال می کند تا در هنگام تماس با اعلان های پیام کوتاه در عملکرد تلفن گویا اختلال ایجاد نشود.
#بررسی وضعیت SIM800l def Init_GSM(): if "OK" in SIM800("AT"): if ("OK" in (SIM800("AT+DDET=1"))) and ("OK" in (SIM800("AT+CNMI =0,0,0,0,0"))) and ("OK" in (SIM800("AT+CMGF=1"))) and ("OK" in (SIM800("AT+CSMP=17,167,0,0"))): # enble DTMF / disable notifications print("SIM800 Module -> Active and Ready") else: print("------->ERROR -> SIM800 Module not found")
def play_wav (file_name): عملکرد بعدی برای پخش پرونده های wav پس از پاسخ به تماس استفاده می شود. ما پرونده های wav از پیش ضبط شده مانند “intro.wav” ، “confirm.wav” ، “cancel.wav” و … را ذخیره کرده ایم. ما باید هر یک از این پرونده ها را بر اساس پاسخ صفحه کلید از طرف کاربر پخش کنیم. تابع play_wav می تواند برای پخش هر پرونده wav به انتخاب ما استفاده شود. مطمئن شوید که این پرونده های wav در همان دایرکتوری کد پایتون شما ذخیره شده اند.
#پخش فایل wav def play_wav(file_name): pygame.mixer.init(8000) pygame.mixer.music.load(file_name) pygame.mixer.music.play() #while pygame.mixer.music.get_busy() == True: #continue
def Call_response_for (phone_number): این مهمترین عملکرد در برنامه است. شماره تلفنی را که باید با آن تماس گرفته شود بدست می آورد و پاسخ آن تماس را فراهم می کند. پاسخ می تواند چیزی مانند NOT_REACHABLE ، CALL_REJECTED ، CONFIRMED، CANCELED و … باشد. این عملکرد از دستورات AT برای برقراری تماس با یک شماره تلفن مشخص استفاده می کند و صدای ضبط شده را پخش می کند. سپس پاسخ DTMF را از طرف تماس گیرنده بررسی می کند و بر اساس پاسخ صدای ضبط شده مناسب را پخش می کند و در آخر به ما می گوید که تماس گیرنده چه چیزی را انتخاب کرده است.
# تماس با شماره مورد نظر و پاسخ NONE, NOT_REACHABLE, CALL_REJECTED, REJECTED_AFTER_ANSWERING, REQ_CALLBACK,CANCELED, CONFIRMED def Call_response_for (phone_number): AT_call = "ATD" + phone_number + ";" response = "NONE" time.sleep(1) ser.flushInput() #پاک کردن داده های سریال if ("OK" in (SIM800(AT_call))) and (",2," in (wait_for_SIM800())) and (",3," in (wait_for_SIM800())): print("RINGING...->", phone_number) call_status = wait_for_SIM800() if "1,0,0,0,0" in call_status: print("**ANSWERED**") ser.flushInput() play_wav("intro.wav") time.sleep(0.5) dtmf_response = "start_over" while dtmf_response == "start_over": play_wav("press_request.wav") time.sleep(1) dtmf_response = wait_for_SIM800() if "+DTMF: 1" in dtmf_response: play_wav("confirmed.wav") response = "CONFIRMED" hang = SIM800("ATH") break if "+DTMF: 2" in dtmf_response: play_wav("canceled.wav") response = "CANCELED" hang = SIM800("ATH") break if "+DTMF: 9" in dtmf_response: play_wav("callback_response.wav") response = "REQ_CALLBACK" hang = SIM800("ATH") break if "+DTMF: 0" in dtmf_response: dtmf_response = "start_over" continue if "+DTMF: " in dtmf_response: play_wav("invalid_input.wav") dtmf_response = "start_over" continue else: response = "REJECTED_AFTER_ANSWERING" break else: #print("REJECTED") response = "CALL_REJECTED" hang = SIM800("ATH") time.sleep(1) #ser.flushInput() else: #print("NOT_REACHABLE") response = "NOT_REACHABLE" hang = SIM800("ATH") time.sleep(1) #ser.flushInput() ser.flushInput() return (response)
def send_message (message, recipient): این برنامه علاوه بر برقراری تماس و دریافت پاسخ ، به ما امکان ارسال پیام را نیز می دهد ، از تابع send_message دقیقاً برای این کار استفاده می شود. رزبری پای پیام و شماره تلفن گیرنده را دریافت می کند و پیام را می فرستد.
#دریافت پیام و شماره تلفن و ارسال پیام def send_message(message, recipient): ser.write(b'AT+CMGS="' + recipient.encode() + b'"\r') time.sleep(0.5) ser.write(message.encode() + b"\r") time.sleep(0.5) ser.write(bytes([26])) time.sleep(0.5) print ("Message sent to customer") time.sleep(2) ser.flushInput() # پاک کردن داده های سریال
def incoming_call (): آخرین عملکردی که برای این پروژه انجام میدهیم شناسایی تعداد تماس گیرنده تماس ورودی است. از آنجا که این سیم کارت قرار است با افراد جدید تماس برقرار کند ، ممکن است برخی سعی کنند در همان زمان با این شماره تماس بگیرند. در این صورت ، از این عملکرد می توان برای بررسی اینکه از کدام شماره تماس ورودی دریافت می کنیم استفاده کرد و سپس بعداً پیامی ارسال کرد یا در صورت لزوم با آنها تماس گرفت
def incoming_call(): while ser.in_waiting: #if I have something in the serial monitor print ("%%Wait got something in the buffer") ser.flushInput() response = SIM800("ATH") #cut the incoming call if "+CLCC" in response: cus_phone = response[21:31] print("%%Incoming Phone call detect from ->", cus_phone) return (cus_phone) else: print("Nope its something else") return "0" return "0"
اکنون که همه توابع تعریف شده اند ، وقت آن است که کد اصلی را بنویسیم که در آن از همه این توابع برای انجام کاری زیبا استفاده خواهیم کرد. اکنون برای نشان عملکرد کلی پروژه، من فقط می خواهم نام مشتری و شماره تلفن مشتری را رمزگذاری کنم. من نام مشتری را به عنوان “AISHA” و شماره را “9877XXXXXXX” برای آزمایش وارد می کنم.
cus_name = "Aisha" cus_phone = "968837XXXX"
در داخل while loop اصلی ، ما ارتباط سریال با نرخ 9600 را با زمان 15 ثانیه شروع خواهیم کرد. برخی از ماژول های SIM800L ممکن است در نرخ های مختلف کار کنند ، مطمئن شوید که پورت COM و نرخ باود (baudrate) را در اینجا وارد کرده اید.
ser = serial.Serial("/dev/ttyUSB0", baudrate=9600, timeout=15) # timeout affects call duration and waiting for response currently 30sec print("Established communication with", ser.name)
در مرحله بعد ، ما تماس تلفنی برقرار می کنیم و پاسخ مورد نیاز مشتری را دریافت می کنیم ، سپس بر اساس پاسخ ، به مشتری پیام می دهیم. به عنوان مثال ، اگر پاسخ تأیید شود ، ما پیامی در رابطه با آن ارسال خواهیم کرد ، به همین ترتیب ، می توانیم پیام را برای پاسخ متفاوت مشتری تغییر دهیم.
print("_____________________IVR START___________________") response = Call_response_for(cus_phone) #place a call and get response from customer print ("Response from customer => ", response) if response == "CONFIRMED": text_message = "Hi " + cus_name + ". Your booking has been confirmed.Thank you. -Circuitdigest" send_message(text_message, cus_phone) if response == "CANCELED": # if the response was to cancel text_message = "Hi " + cus_name + ". Sorry that you have decided to cancel your booking. If you cancled by mistake, kindly contact us through phone. -Circuitdigest" send_message(text_message, cus_phone) if ((response == "CALL_REJECTED") or (response == "REJECTED_AFTER_ANSWERING")): # if the response was rejected text_message = "Hi " + cus_name + ". We from circuitdigest.com have been trying to reach you, to confirm your booking. You will receive another call within few minutes, we kindly request you to answer it. Thank you" send_message(text_message, cus_phone) print("_____________________IVR END___________________")
تست سیستم تلفن پاسخگو (گویا – IVR)
مطمئن شوید که اتصالات درست انجام شده و برد Raspberry Pi و GSM روشن است.
قبل از اجرای برنامه ، اطمینان حاصل کنید که پورت COM صحیح در کد ذکر شده است. برای من “/ dev / ttyUSB0” بود. سپس با کلیک راست روی نماد بلندگو مطمئن شوید که صدا روی جک AV تنظیم شده است و همچنین از کم بودن میزان صدا اطمینان حاصل کنید.
در مرحله بعدی ، فقط شماره تلفن و نام مشتری را طبق انتخاب خود تغییر دهید یا برنامه را تغییر دهید تا شماره و نام را از API اکسل یا cloud دریافت کنید.
این برنامه با شماره داده شده تماس گرفته و از گیرنده بازخورد dtmf دریافت می کند. همچنین فایلهای صوتی مرتبط را پخش کرده و بر اساس پاسخی که گیرنده دریافت می کند ، یک پیام متنی ارسال می کند. چند پیام دریافت شده توسط تلفن من در زیر نشان داده شده است.
شما می توانید به راحتی فایل های صوتی و پیام های مورد نیاز برنامه خود را تغییر دهید. امیدوارم از این پروژه لذت برده باشید و چیز مفیدی یاد گرفته باشید.
موارد موجود در فایل : سورس کامل، صدا های مورد نیاز
برای دانلود فایل ها باید حساب کاربری داشته باشید ثبت نام / ورود
سلام
اگر تغذیه رزبری رو قطع کنیم و تغذیه sim800l هنوز وصل باشه یا برعکس، مشکلی برای ماژول ها یا رزبری پای به وجود نمیاد؟