بعد از تست Android Tv مدت ها بود میخاستم Android Things یا همون اندروید چیزها رو تست کنم و تو این مدت چندتا پست جالب دیدم که درباره اندروید چیزها بود. ترکیبی از این کارهارو سعی کردم تو این کار انجام بدم. :)
کاری که قراره تو این پست باهم انجام بدیم ساخت یه برد ساده و متصل کردن اون به پینهای رزبریپای و کنترل قطعات روی برد توسط یک ربات تلگرام هستش. مثلا با ارسال دستور BEEP به ربات مورد نظر صدای BEEZER روی برد فعال بشه. (سورس نهایی) (فیلم عملکردنهایی)
موارد لازم: (این قطعات رو با یه جستجوی ساده میتونید انلاین تهیه کنید.)
- یه دونه رزبری پای ۳
- ایمیج اندروید چیزها
- بردبورد
- الایدی
- یه دونه Beezer
- یه اکانت تلگرام
- ترجیحا ماوس و کیبرد اضافی برای استفاده روی رزبری
- از همه مهمتر یه وقت مناسب برای انجام :)
ابتدا ایمیج اندروید چیزها رو از این آدرس دانلود کنید. (قاعدتا تحریم هستیم، پس: فغان از محدودیت ها :( )
ایمیج رو توسط ابزار های رایت ایمیج روی رزبری رایت کنید.
به رزبری یک عدد کابل شبکه برای اتصال و اجرای برنامه در قدم های بعدی متصل کنید.
رزبری رو روشن کنید با تصویر زیر روبرو میشین:
پایین تصویر آدرس IP مورد نظر برای اتصال به دستگاه وجود. درصورتی که لازم بود از وایفای استفاده بشه توسط کد زیر میتونید رزبری رو به SSID مورد نظر متصل کنید. (قبل از اجرای کد های زیر توسط دستور adb connect yourIp به رزبری متصل بشید)
adb shell am startservice \-n com.google.wifisetup/.WifiSetupService \-a WifiSetupService.Connect \-e ssid <Network_SSID> \-e passphrase <Network_Passcode>
اندروید استدیو رو آتیش کنید و یک پروژه جدید بسازید. نسخه api مورد نظر رو ۲۴ یا بالاتر انتخاب کنید. (سورس پروژه نهایی از این آدرس در دسترس هست)
در اولین قدم نیاز هست کتابخانه کاربا اندروید چیزها رو به پروژه خودتون اضافه کنید. فایل build.gradle از ماژول app رو باز کنید و این خط رو در قسمت dependecy های پروژهتون اضافه کنید.
provided 'com.google.android.things:androidthings:0.1-devpreview'
در قدم بعدی این خط رو در تگ application در فایل manifest برنامهتون وارد کنید.
<uses-library android:name="com.google.android.things"/>
برای اینکه برنامهشما به عنوان لانچر اصلی دستگاه تعریف بشه این فیلترها رو به اکتیویتی اصلی خودتون اضافه کنید.
<activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.IOT_LAUNCHER"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </activity>
برنامه تمام شده و قابل اجرا هست. قبل از اینکه برنامه رو اجرا کنید توسط دستور adb devices چک کنید که رزبری توسط اندروید استدیو قابل شناسایی باشه. اگر هنوز اون رو متصل نکردید میتونید توسط دستور adb connect IP و همون IP نشون داده شده در صفحه اصلی به دستگاهتون متصل کنید.
توسط کد زیر میتونید لیست پینهای برد خودتون رو مشاهده کنید. (پینهای قابل برنامهریزی)
PeripheralManagerService service = new PeripheralManagerService(); Log.e("AndroidThings", "GPIOs: " + service.getGpioList() ); E/AndroidThings: GPIOs: [BCM12, BCM13, BCM16, BCM17, BCM18, BCM19, BCM20, BCM21, BCM22, BCM23, BCM24, BCM25, BCM26, BCM27, BCM4, BCM5, BCM6]
قبل از ادامه کار یه توضیح کوتاه درباره رزبریپای۳ بدم که تعداد ۴۰ عدد پین روی برد وجود داره که شما میتونید از پینهایی که دستور بالا بهشون اشاره کرده استفاده کنید. برای اینکه بدونید اسم هر پین دقیقا کدوم پین رزبری هست میتونید شماتیک دستگاه رو در اینترنت سرچ کنید و یا از این سایت استفاده کنید.
تو این پروژه دوتا LED ساده و یک BEEZER استفاده شده که LED ها به پینهای BCM 17 - 27 و BEEZER هم به پین BCM 22 متصل هست. تمام پینهای منفی هم به یه دونه از GND های رزبری متصل هست.
توسط کدهای زیر میتونید یک پین رو فعال و غیرفعال کنید:
String PIN_LED_BLUE = "BCM17"; Gpio mGpioBlue; PeripheralManagerService service = new PeripheralManagerService(); try { mGpioBlue = service.openGpio(PIN_LED_BLUE); mGpioBlue.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW); } catch (IOException e) { Log.e(TAG, e.getMessage()); } mGpioBlue.setValue(Boolean);
در قدم بعدی میخایم یه ربات تلگرام بسازیم و دستوراتی که به ربات ارسال میشه رو پردازش کنیم. تا با ارسال دستور مشخصی پین مورد نظرمون رو فعال و غیرفعال کنیم. برای ارتباط با ربات تلگرام از این کتابخونه استفاده میکنیم.
کتابخونه رو به پروژه اضافه میکنیم:
compile 'com.github.pengrad:java-telegram-bot-api:3.3.0'
این کتابخونه به OkHttp هم احتیاج داره برای ارتباط با سرور پس اون رو هم به کتابخونههای پروژه اضافه میکنیم.
compile 'com.squareup.okhttp3:okhttp:3.8.1'
میریم سراغ خود تلگرام، میخایم یه ربات بسازیم و Token ربات رو به کتابخونه مورد نظر بدیم تا بتونه پیامهای ارسال شده رو دریافت کنه. برای اینکار به ربات BotFather مراجعه میکنیم و پس از دادن یه نام مناسب و یه یوزرنیم که با bot تموم میشه میتونیم توکن ربات مورد نظرمون رو داشته باشیم. (در ادامه با همین ربات میتونید تصویر ربات و اطلاعات تکمیلی رو هم وارد کنید)
توسط کد زیر میتونیم پیامهای ارسالی به ربات مورد نظرمون رو دریافت کنیم و بخونیم؛
TelegramBot bot = TelegramBotAdapter.build(BOT_TOKEN); GetUpdates getUpdates = new GetUpdates().limit(100).offset(0).timeout(10); bot.setUpdatesListener(new UpdatesListener() { @Override public int process(List<Update> updates) { for (Update update : updates) { Message msg = update.message(); if (msg != null) { String txt = msg.text(); } } return UpdatesListener.CONFIRMED_UPDATES_ALL; } });
تو این پروژه میایم یه شرط ساده رو بررسی میکنیم که اگه پیام LED BLUE اومد چراغ آبی و LED WHITE چراغ سفید روشن بشه و با دستور BEEP صدای بیزر فعال بشه. هم چنین با ارسال مجدد این دستور ها عملکرد برعکس داشته باشه و در صورت فعال بودن پین مورد نظر اون پین غیرفعال بشه.
پس کد تکمیل شده ما این میشه :
bot.setUpdatesListener(new UpdatesListener() { @Override public int process(List<Update> updates) { for (Update update : updates) { Message msg = update.message(); if (msg != null) { String txt = msg.text(); tv.append("\n" + txt); if (txt.trim().startsWith("LED")) { Log.d(TAG, "LED COMMAND"); String[] data = txt.split(" "); if (data[1].equalsIgnoreCase("blue")) { Log.d(TAG, "Blue pin"); setPin(PIN_LED_BLUE); } else if (data[1].equalsIgnoreCase("white")) { Log.d(TAG, "White pin"); setPin(PIN_LED_WHITE); } }
اما صبر کنید یه مشکلی هست !! چه مشکلی ؟؟؟
ربات تلگرام شما احتمالا هیچ پیامی رو پردازش نمیکنه. دلیلش هم اینه که تاریخ دستگاه مشکل داره ! ( احتمالا تو بروزرسانی های بعدی اندروید چیزها درست میشه) و به دلیل Https بودن درخواست ها سرور تلگرام تو handShake کردن با برنامه شما به مشکل میخوره.
اما الان چطوری تاریخ صحیح رو روی دستگاه تنظیم کنیم؟! شما تنظیماتی دیدید؟ (نگران نباشین میشه یه کاریش کرد :) )
چندتا راه هست برای بروزرسانی تاریخ دستگاه:
- استفاده از دستور های ADB برای بروزرسانی تاریخ (من نتونستم جواب بگیرم از این روش! )
- نوشتن یک برنامه با دسترسی SET_TIME و قرار دادن این برنامه در لیست برنامه های سیستمی برای بروزرسانی همیشگی زمان (این روش جواب میده ولی دردسر های مخصوص خودش رو هم داره)
- نوشتن یک Intent برای رفتن به صفحه تنظیمات دستگاه :) و تغییر تاریخ و ساعت
برای روش سوم توسط خط زیر میتونید وارد تنظیمات دستگاه بشین و تاریخ و ساعت دستگاه رو تنظیم کنید.
startActivityForResult(new Intent(android.provider.Settings.ACTION_SETTINGS), 0);
در نهایت پروژه رو اجرا کنید و خروجی رو ببنید و لذت ببرید. مشاهده خروجی نهایی روی آپارات
دیگه چیکار میشه کرد:
یه LCD بگیرید و پیامهای ارسالی رو روی LCD نشون بدید.
از دوربین استفاده کنید تو این پروژه.
این پروژه رو بسازید و بزنید قدش :)))
سنسور های الکترونیک قیمت زیادی ندارند و از اکثر سایت ها قابل تهیه هستند. با دیدن لیست سنسورها یه عالمه ایده جالب به ذهنتون میزنه :)
امیدوارم این پست باعث بشه شماهم اندروید چیزها رو تست کنید :))))
منابعی که از اونها برای این پروژه استفاده شد: