سلام به همه.
بعدازاینکه من چالش LED قسمت قبل رو حل کردم زئوس یه چالش باحال تر برام گذاشت. چالش به این صورت بود که من باید با دوتا LED به رنگهای قرمز و سبز یه نور زرد تولید میکردم. یعنی طوری که باید از کاربر سؤال میشد میخواد چه رنگی رو انتخاب کنه؟ و کاربر ۳ حق انتخاب داشته باشه: حالت اول رنگ قرمز، حالت دوم رنگ سبز و حالت سوم رنگ زرد.
وسایلی که حق داشتم انتخاب کنم:
- رزبری پای (من یدونه نسخه ۴ انتخاب کردم)
- برد بورد ( کوچیک یا بزرگش فرقی نداره)
- دو تکه سیم نر و ماده (ترجیحاً در ۲ رنگ متفاوت من خودم از قهوهای و قرمز استفاده کردم)
- سه تکه سیم دوسر نر (ترجیحاً با رنگهای متفاوت)
- دوتا LED (یکی قرمز و دیگری سبز)
- یدونه مقاومت ۱۰ اهم
یه کوچولو فکر کردم و به این نتیجه رسیدم که طبق شکل زیر یه مدار رسم کنم:
حالا با این مدار من ۳ تا نور میتونم تولید کنم. حتماً میپرسید چطور؟
جواب خیلی راحته. اگه هرکدوم از ورودیهای ما ۰ و دیگری ۱ باشه ما میتونیم یه نور رو ببینیم. حالا اگه هرکدوم از ورودی و خروجیها رو توی بازه ۵۰ هرتز یا بیشتر ۰ و ۱ کنیم چی؟ چشم ما نمیتونه این حجم از روشن و خاموش شدن رو درک کنه و به نظرش دوتا LED ها روشنه. منطق برنامه رو درست گفتم. حالا باید برم و پیاده سازی کنم.
اتصالات سخت افزاری
تو قدم اول مداری که تو عکس میبینید رو روی برد بورد وصل کردم. پس با توجه به این عکس:
سیم قهوهای رو به پین شماره ۷ رزبری و پورت مثبت سمت چپ برد بورد وصل کردم. سیم قرمز رو هم به پین شماره ۸ رزبری و پورت مثبت ستون سمت راست وصل کردم.
یدونه از سیمهای دوسر نر رو از ستون مثبت سمت راست برد بورد به پورت شماره J۷ وصل کردم. مقاومت رو برداشتم و یه سر اون رو به پورت شماره I۷ و سر دیگه اون رو به پورت شماره E۱۲ وصل کردم. دوتا سیمهای دوسر نر رو از ستون مثبت سمت چپ به ترتیب یکی رو به پورت شماره A۱۰ و A۱۵ وصل کردم. LED قرمز رو برداشتم و سر منفی اون رو به پورت شماره C۱۵ و سر مثبت رو به پورت شماره C12 وصل کردم. LED سبز رو برداشتم و سر مثبت اون رو به پورت D۱۲ و سر منفی اون رو به پورت D۱۰ وصل کردم.
قسمت برنامه نویسی
تبریک میگم به خودم. حالا فقط مونده بود برنامه نویسی برای حل این چالش LED.
طبق روال قبل کتابخانههای مورد نظر رو فراخانی کردم:
import RPi.GPIO as GPIO import time
تنظیمات پورتها رو هم مثل قبل اینجا تعریف کردم:
GPIO.setmode(GPIO.BCM) red_pin=14 green_pin=4 GPIO.setup(red_pin,GPIO.OUT) GPIO.setup(green_pin,GPIO.OUT)
الآن من به ۳ تا تابع نیاز داشتم برای رنگ قرمز، سبز، زرد. اینم اینجا تعریف کردم:
def red(): GPIO.output(red_pin,True) GPIO.output(green_pin,False) def green(): GPIO.output(red_pin,False) GPIO.output(green_pin,True) def yellow(): while True: red() time.sleep(0.013) green() time.sleep(0.013)
اگه به تابع yellow دقت کنید میبینید که داخل یه حلقه بی نهایت داره توابع مربوط به رنگهای قرمز و سبز رو به ترتیب با ۰/۱۳ ثانیه داره فراخانی میکنه. در این سرعت چشم انسان نمیتونه تشخیص بده که الان LED ها داره خاموش و روشن میشه، پس مغز ما فکر میکنه الآن روشنه.
دیگه بقیش که مث آب خوردن بود. باید از کاربر میپرسیدم میخوای چیکار کنی و بعد هم تابع مربوط به خودش رو فراخوانی کنم. با این دستور از کاربر میپرسم الآن میخوای چیکار کنی؟
FLAG=str(input("select your choise \n r -> red \n g-> green \n r_g -> yellow\n *** q for quiet ***"))
کاربر اگه g رو وارد کنه LED سبز براش روشن میشه. اگه r رو وارد کنه LED قرمز براش روشن میشه. اگه هم r_g رو وارد کنه براش نور زرد تولید میشه. که با این کدها ادامه ماجرا براش در پشت صحنه انجام میشه:
if FLAG == "r": red() elif FLAG =="g": green() elif FLAG=="r_g": yellow() elif FLAG=='q': exit() else: print("wrong data")
تا اینجا درست پیشرفته بودم که ناگهان زئوس گفت: “باید تا برنامه اجرا میشه هربار از کاربر سؤال بشه الآن میخوای چه عملیاتی انجام بدی و با وارد کردن دستور، کار قبلی متوقف و کار جدید شروع بشه.”
من که ۸۰٪ راه رو رفتم، یکم فکر کردم دیدم خب تابعهای red و green که برای led اصن چالش خاصی نداره اما تابع مربوط به yellow چون داره توی حلقه بی نهایت میره نمیشه همین طوری به صورت عادی باهاش برخورد کرد. به خودم گفتم اگه تو thread بزارمش ممکنه درست کارکنه؟
امتحان کردم و جواب گرفتم:
while True: FLAG=str(input("select your choise \n r -> red \n g-> green \n r_g -> yellow\n *** q for quiet ***")) if FLAG == "r": red() elif FLAG =="g": green() elif FLAG=="r_g": threading.Thread(target=yellow).start() elif FLAG=='q': exit() else: print("wrong data")
حالا یه چیزی هم برای اینکه اون thread متوقف بشه باید بزارم:
try: while True: FLAG=str(input("select your choise \n r -> red \n g-> green \n r_g -> yellow\n *** q for quiet ***")) if FLAG == "r": stop_thread=True red() elif FLAG =="g": stop_thread=True green() elif FLAG=="r_g": stop_thread=False threading.Thread(target=yellow).start() elif FLAG=='q': stop_thread=True exit() else: print("wrong data") finally: GPIO.output(red_pin,False) GPIO.output(green_pin,False)
اون سه تا تابع رو هم به این صورت تغییر دادم:
def red(): GPIO.output(red_pin,True) GPIO.output(green_pin,False) def green(): GPIO.output(red_pin,False) GPIO.output(green_pin,True) def yellow(): global stop_thread while True: red() time.sleep(0.013) green() time.sleep(0.013) if stop_thread: break
کد کامل چالش LED
به همین راحتی این چالش هم حل شد. شما میتونید کد کامل برنامه رو اینجا ببینید:
import RPi.GPIO as GPIO import time import threading GPIO.setmode(GPIO.BCM) sleep_time=0.20 red_pin=14 green_pin=4 GPIO.setup(red_pin,GPIO.OUT) GPIO.setup(green_pin,GPIO.OUT) #### def red(): GPIO.output(red_pin,True) GPIO.output(green_pin,False) def green(): GPIO.output(red_pin,False) GPIO.output(green_pin,True) def yellow(): global stop_thread while True: red() time.sleep(0.013) green() time.sleep(0.013) if stop_thread: break ### try: while True: FLAG=str(input("select your choise \n r -> red \n g-> green \n r_g -> yellow\n *** q for quiet ***")) if FLAG == "r": stop_thread=True red() elif FLAG =="g": stop_thread=True green() elif FLAG=="r_g": stop_thread=False threading.Thread(target=yellow).start() elif FLAG=='q': stop_thread=True exit() else: print("wrong data") finally: GPIO.output(red_pin,False) GPIO.output(green_pin,False
منبع:سیسوگ