2016幎12æãGoogleã¯Android Thingsã®æåã®éçºè ãã¬ãã¥ãŒããŒãžã§ã³ã®ãªãªãŒã¹ãçºè¡šããŸãã ã ãã以æ¥ããããžã§ã¯ãã¯å€§ããå€ãããŸããã ãã¬ãã¥ãŒçã®ã¿ãåŒãç¶ãå©çšå¯èœã§ããããã¹ãŠã®ã¹ãããã§ãã©ãããã©ãŒã ã«æ°æ©èœãè¿œå ããããµããŒããããããã€ã¹ã®æ°ãå¢ããŠããŸãã
çŸå®ã®äžçã§IoTããã€ã¹ã䜿çšããæ°ããäŸãæ¯æ¥ããããã©ãããã©ãŒã èªäœãããé åçã«ãªã£ãŠããŸãã Live Typingã®ç§ãã¡ã¯ãã¢ãã®ã€ã³ã¿ãŒãããã®èå³æ·±ãäžçã«é£ã³èŸŒãã§ãç§ãã¡ã®çµéšã«ã€ããŠè©±ãããšã決ããŸããã ãã®èšäºã¯ãAndroid Thingsã«ã€ããŠèããããšããããŸãããè©ŠããŠã¿ãã®ãæã人åãã§ãã ãŸãããã¹ããŒãããã¯ããã©ã®ããã«å®è£ ããèªç€Ÿã®ãªãã£ã¹ã§äœ¿çšãããã«ã€ããŠã説æããŸãã
ã¢ã€ãã¢ã®èª¬æ
åé¡1ïŒåœç€Ÿã¯ãé»åãããžã·ã¹ãã ãšã¬ã©ã¹ãã¢ãåãããªãã£ã¹ãåããŠããŸãã å€ãã®å ŽåãåŸæ¥å¡ã¯èªå® ã§ã«ãŒããå¿ããããåã«ã«ãŒããªãã§å€ã«åºãŠãååãããã¯ãããé»è©±ããŠæ»ã£ãŠããŸãã ã«ãŒãã¯ããªãã£ã¹ã®å å€ã§ç£æ°ããã¯ã«é©çšããå¿ èŠããããŸãã å åŽã§ã«ãŒããããŒãã«çžã£ãã ããªããå€åŽããããŒãªãã§ãªãã£ã¹ã«å ¥ãããšã¯è§£æ±ºãããåé¡ã§ãã
åé¡çªå·2ïŒé±æ«ã«ã¯ãããŸããŸãªçš®é¡ã®äŒè°ããªãã£ã¹ã§éå¬ãããŸãã åºåžè ã®å€§éšåã¯ååã§ã¯ãããŸããã ãã®æ°ã¯ããŸããŸã§ãããã©ãã ãå€ããŠããåžžã«ãã¢ãéãããŸãŸã«ããããã«ãéšå€è ã«ããŒãæž¡ãããšã¯ã§ããŸãããããã¯ç§ãã¡ã®è²¡ç£ã«ãšã£ãŠå®å šã§ã¯ãããŸããã ãã®ãããç¹å¥ãªãå人çšãã¢ãã³ããä»»åœããããå¿ èŠä»¥äžã«ãã¢ããµããŒãããå¿ èŠããããŸãã
ãã¹ã¹ã«ãŒã·ã¹ãã ãåæãåé€ããŸãã¯ã¢ããã°ã¬ãŒãããæš©å©ã¯ãããŸããããå€éšããã®æ¥ç¶ã«ã¯å¶éã¯é©çšãããŸããã ãã¢ã«ãµãŒããã©ã€ããè£ åããé¡èªèãæåããå Žåãæ¥ç¶ãããã«ãŒããèªã¿åãã»ã³ãµãŒã«å転ãããããšã«ããŸããã é¡åçã¯ã«ã¡ã©ã«ãã£ãŠæäŸãããŸãã ãããã£ãŠãäžçš®ã®ã¹ããŒããã¢ããã¯ãååŸããŸãã
ãã®ãããªããã¯ã䜿çšãããšããã©ãã¯ãžã£ãã¯ãšå¹ åºãå¯èœæ§ãæã€ç¬èªã®èå¥ã·ã¹ãã ã䜿çšã§ããŸãã ïŒããšãã°ãåŸæ¥å¡ã®é¢çœãåçããã瀟å ã§éã³å¿ã®ãã䜿çšã®ããã«ã¹ããã«ãŒãäœæã§ããŸãïŒã 2çªç®ã®åé¡ã«ã€ããŠè©±ãå Žåãåã§ã¯äŒè°ã®åå è ã®åçãç»é²ããŠã¹ãããã§ããŸãã ãããã§ãã
ããã«ãã¢ã€ãã¢ã¯ä»éãããã¥ã¢ã³ã¹ãšè³ªåã«å²ãŸããŠããŸããã åçã®æ®åœ±ãéå§ããã³çµäºããã¿ã€ãã³ã°ã¯ïŒ åçãæ®ãé »åºŠãšé·æé å€åæéå€ãæéã®äžã§ã·ã¹ãã ãåæãã䟡å€ã¯ãããŸããïŒ ã·ã¹ãã ãèŠèŠåããæ¹æ³ã¯ïŒ ããããããã«ã€ããŠã¯ããã«åå¥ã«ã ãããžã§ã¯ãã®åºç€ãšããŠãå ¬åŒã®Android ThingsããŒãžããDoorbellã®äŸãåãäžããŸããã å ã®äŸã¯ããã«ããšåŒã°ããŸãããã·ã¹ãã ãŠãŒã¶ãŒã«æå°éã®åŽåã§ãã¢ã®ããã¯ã解é€ããŠããããèŠç¥ãã¬äººã¯äžã«å ¥ããŸããã§ããã ãããã£ãŠããã¹ããŒãããã¯ããšåŒã¶æ¹ãæ£ãããšèããŸããã
è¬èŸ
æåã¯äœããããŸããã§ããã Raspberryèªäœããã¢ã¯ã»ãµãªãããããã®çµéšããããŸãããèšäºãšããã¥ã¡ã³ãããåŸãããçè«çç¥èã®ã¿ã§ãã Android Thingsã§åããŠãã¬ã€ããã®ã¯ã Mobilatoriumã®ã¡ã³ããŒããªã ã¹ã¯åžã®ã·ããªã¢ã®ITéŠéœã§éå¬ããCodeLabã§ãã ã Google Cloud Visionã®ä»£ããã«ã Tensor Flowã« FindFaceå®è£ ãå®è£ ãããããžã§ã¯ããããã«éå§ããŸããã ããã¯ãšã³ããã©ã®ããã«æ©èœãããã«èå³ãããå Žåã¯ãåªããèšäºãLooking for Familiar Facesããèªãããšãã§ããŸããèè ã¯ãé¡èªèã䜿çšããããã®åçãšã¢ã«ãŽãªãºã ã«ã€ããŠè©³ãã説æããŠããŸãã ããã§ãªãå Žåã¯ãäžèšã®CodeLabã§è¡ã£ãããã«ã Google Cloud Vision + Firebase Realtime Databaseãã³ãã«ã䜿çšã§ããŸãã
ç§ãã¡ããªãã£ã¹ã«æ»ã£ããšããåŸæ¥å¡ã®ãã·ã£ã¯å¿ èŠãªãã¹ãŠã®ã³ã³ããŒãã³ããšãæè¿è³Œå ¥ããRaspberry Pi3ãããæã£ãŠããŠããã®ãããªãã®ã«å€¢äžã«ãªã£ãŠããããšãããããŸããã Arduinoã®ç 究ã§[å€åŠæ]ïŒ https://vk.com/mobilatorium?w=wall-130802553_81%2Fall ïŒãè²»ãããç·ãã¡ã®ã³ã³ããŒãã³ãããããŸããã æäŸãããããŒããŠã§ã¢ã«æè¬ããŸãã
ä»å±å
ã¹ããŒãããã¯ãå®è£ ããã«ã¯ã次ã®ãã®ãå¿ èŠã§ããã
- Raspberry Pi 3-1å;
- MicroSD 8Gb-1å;
- NoIR Camera V2-1å;
- ãã¬ããããŒã-1å;
- èµ€å€ç·PIRã¢ãŒã·ã§ã³ã»ã³ãµãŒã¢ãžã¥ãŒã«-1å;
- SG90ãµãŒãã¢ãŒã¿ãŒ-1å;
- ãã©ãæµæåšïŒå ã»ã³ãµãŒïŒ-1å;
- ããã·ã¥ãã¿ã³-1å;
- LED-3å;
- æµæåšïŒ1kïŒ-3å;
- æµæåšïŒ10kïŒ-1å;
- ãã³ãžã£ã³ããŒç·-å€ãã®éšåã
- 絶çžããŒã-1å
ãã¹ãŠã®ã³ã³ããŒãã³ãã¯ãäžåœã®ãµã€ãã§ç°¡åã«èŠã€ããããšãã§ããå®äŸ¡ã«æ³šæã§ããŸãããŸããæ€çŽ¢ããããããã«ãç¹ã«ååã¯è±èªã®ãŸãŸã«ããŸããã ãããã®è²»çšãçŽ100ã125ãã«ã«ãªãããšã¯èšåãã䟡å€ããããŸãã æãé«äŸ¡ãªã³ã³ããŒãã³ãã¯ãã«ã¡ã©ãšRaspberry Pi3èªäœã§ãã
å®è£
ç解ãæ·±ããããã«ãå®è£ ã®èª¬æãåå¥ã®ã¹ãããã«åããŸãã ã¹ããŒã ãéšåçã«çµã¿åããããšãä»»æã®ã¹ãããã§ç»åã埩å ããæ¹ã䟿å©ã§ãã ã³ãŒãã¯ååã§ã¯ãããŸãããAndroidçšã®ã¢ããªã±ãŒã·ã§ã³ãå°ãªããšã1ã€æžããŠããã°ãåé¡ã¯ãªããšæããŸãã éçºã«ã¯äœ¿ãæ £ããAndroid Studioã䜿çšããŸãã DaggerãRxJavaãRetrofitãOkHttpãTimberãªã©ã®ãæ°ã«å ¥ãã®ã©ã€ãã©ãªãšãã¬ãŒã ã¯ãŒã¯ã䜿çšããããšãã§ããŸãã
å§ããåã«ã Android Thingsã®ç°¡åãªçŽ¹ä»ãšRaspberry Pi3ã®ãã³ã«æ £ããŠããå¿ èŠããããŸãã ãŸãããã®ãã³é åã®ã«ã©ãŒåçã¯åªããèŠèŠçã¬ã€ãã§ãããäœåºŠã圹ç«ã¡ãŸãã
Raspberry Piã¯ãç°ãªãããŒããŠã§ã¢ã€ã³ã¿ãŒãã§ã€ã¹ã®ã»ããããµããŒãããŠããŸãã ãã ããäž»ã«GPIO ïŒæ±çšå ¥åºåïŒããã³PWM ïŒãã«ã¹å¹ å€èª¿ïŒã«é¢å¿ããããŸãã ãããã¯ããããžã§ã¯ãã®å®è£ äžã«ããŒããšã»ã³ãµãŒã®éã®çžäºäœçšã®äž»ãªæ¹æ³ã«ãªããŸãã
ããŸããŸãªåšèŸºæ©åšã®ã©ã€ãã©ãªããã§ã«äœæãããŠããããããã®å€ãã¯ããã«äœ¿çšã§ããŸãã ãããã£ãŠãæ°ããã»ã³ãµãŒã®çµ±åãéå§ãããšãã¯ããŸããã®ãªããžããªãšãã®ãªããžããªã«æ £ããŠãã ããã å€ãã®ãã©ã€ããŒãããã§ã³ã³ãã€ã«ãããŠããŸãã ãããããããªãã¯æ£ãããã®ãèŠã€ããã§ãããã ããã§ãªãå ŽåãGoogleã¯Android Framework Servicesã®æ©èœãæ¡åŒµããç¹å¥ãªãŠãŒã¶ãŒãã©ã€ããŒã®æŠå¿µãæäŸããŠããŸã ã ããŒããŠã§ã¢ã§çºçããŠããããšããã¬ãŒã ã¯ãŒã¯ã«ãªãã€ã¬ã¯ãããæšæºã®Android APIããŒã«ã§åŠçããŠãç¬èªã®ãã©ã€ããŒãäœæã§ããããã«ããŸãã ç°¡åã«èšãã°ãä»»æã®ãã©ã€ããŒã§ã®äœæ¥ã¯ã次ã®æé ã«åããããšãã§ããŸãã
- ãã©ã€ããŒãªããžã§ã¯ããäœæãã
- ãã©ã€ããŒãç»é²ããŸãã
- ã€ãã³ãã賌èªãã
- ç»é²è§£é€ããã³ç»é²ã®ãã£ã³ã»ã«ã
ãã®èšäºã§ã¯ãç¬èªã®ãã©ã€ããŒãå®è£ ããäŸãèŠãããšãã§ããŸãã
ã¹ããã1ïŒAndroid Thingsãã€ã³ã¹ããŒã«ãã
Raspberry Pi3ã«ææ°ã®Android Thingsã€ã¡ãŒãžãã€ã³ã¹ããŒã«ããŸãã ããŸããŸãªãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã®ã€ã¡ãŒãžãã€ã³ã¹ããŒã«ããããã®æé ãžã®ãªã³ã¯ããããŸãã
HDMIã±ãŒãã«ãä»ããŠãã£ã¹ãã¬ã€ãRaspberryã«æ¥ç¶ãããšããã¹ãŠãæ£åžžã«ã€ã³ã¹ããŒã«ãããããšã確èªã§ããŸãã ãã¹ãŠãæ£åžžã§ããã°ãç»é¢ã«Android Thingsã®èµ·åã¢ãã¡ãŒã·ã§ã³ã衚瀺ãããŸãã
WiFi. Android Things IP- WiFi .
, , Raspberry adb .
$ adb connect Android.local
ã¹ããã2ïŒã¢ããªã±ãŒã·ã§ã³ãäœæããŸãã
Androidã®ã¡ãŒã«ãŒãéããŠæ°ããã¢ããªã±ãŒã·ã§ã³ãäœæããŸãã ããã¯å¿ é ã§ã¯ãããŸããããããªãã¯ãèªåã®ç»é¢ãæ²èŒãããã°ã©ã ã®æšæºçãªAndroidã®ãŠã£ãžã§ããã®åäœãå¯èŠåããããšãã§ããŸãã ãã§ãã¯ã¢ãŠãåã®Androidç©äºã®ã¢ããªã±ãŒã·ã§ã³ãäœæããããã®å®å šãªæç€ºå ¬åŒãŠã§ããµã€ãäžã«ãæã ã¯å¯äžã®ãã€ã©ã€ããèŠãŠãããŸãã
æå°èŠä»¶ïŒ
- Androidã®ã¡ãŒã«ãŒ2.2以äžã
- SDKããŒã«25.0.3以äžã
- åSDK 24以äžã
- ã¿ãŒã²ããSDK 24以äžã
è¿œå app/build.gradle
ç§ãã¡ã«å¿
èŠãªAPIãžã®ã¢ã¯ã»ã¹æš©ãäžããã§ããããäŸåæ§ã®Androidç©äºãµããŒãã©ã€ãã©ãªãæšæºã®Android SDKã®äžéšã§ã¯ãããŸããã
dependencies { ... provided 'com.google.android.things:androidthings:0.4-devpreview' ... }
devpreview' dependencies { ... provided 'com.google.android.things:androidthings:0.4-devpreview' ... }
åã¢ããªã±ãŒã·ã§ã³ã¯ãïŒäŸãã°æŽ»åããµãŒãã¹ããã³ãããã¥ãŒããã¿ã³ãã¢ããªã±ãŒã·ã§ã³ãã®ContentProviderãªã©ãšããããã«æšæºã¯ã©ã¹ã§ïŒã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããããã®åºæ¬çãªããã±ãŒãžããããŠããããã©ã«ãã®Androidã©ã€ãã©ãªãé¢é£ä»ããããŠããŸãã
ããããããã€ãã®ããã±ãŒãžã¯ãç¬èªã®ã©ã€ãã©ãªã§ãã ã¢ããªã±ãŒã·ã§ã³ããããã®ãã±ããã®ããããããã®ã³ãŒãã䜿çšããŠããå Žåãããã¯åœŒããã®ããã±ãŒãžãšææºããããšãæ瀺çã«èŠæ±ããªããã°ãªããŸããã ããã¯ãåäžã®èŠçŽ <çšéã»ã©ã€ãã©ãªãŒ>ãä»ããŠè¡ãããŸãã
<application ...> ... <uses-library android:name="com.google.android.things"/> ... </application>
"com.google.android.things" /> <application ...> ... <uses-library android:name="com.google.android.things"/> ... </application>
Androidã®ç©äºã¯ããªããåæã«äžã€ã ãã®ã¢ããªã±ãŒã·ã§ã³ãã€ã³ã¹ããŒã«ããããšãã§ããŸãããç§ãã¡ã®ã»ãšãã©ã¯ããã§ã¯ãããŸããã ãã®å¶éã®ããã宣èšããããšãå¯èœã§ãã<intent-filter>
掻åãäž¡æ¹ã®ããã«IOT_LAUCHER
ããªãã¯ãèµ·åããã€ã¹ã§ããã«ãã®æŽ»åãå®è¡ããããã«ããã©ã«ãããããšãã§ããŸãAndroidManifestã¢ããªã±ãŒã·ã§ã³ã§ã ãŸããæšæºã®ãŸãŸ<intent-filter>
ã¢ã»ã³ããªãšdeployaåŸã«ç§ãã¡ã®ã¢ããªã±ãŒã·ã§ã³ãå®è¡ããããšãã§ããã®Android Studioã«ã
<activity ...> ... <!-- Launch activity as default from Android Studio --> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> <!-- Launch activity automatically on boot --> <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>
ã®Androidã¡ãŒã«ãŒ- > <activity ...> ... <!-- Launch activity as default from Android Studio --> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> <!-- Launch activity automatically on boot --> <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>
" /> <activity ...> ... <!-- Launch activity as default from Android Studio --> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> <!-- Launch activity automatically on boot --> <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>
" /> <activity ...> ... <!-- Launch activity as default from Android Studio --> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> <!-- Launch activity automatically on boot --> <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>
- > <activity ...> ... <!-- Launch activity as default from Android Studio --> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> <!-- Launch activity automatically on boot --> <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>
" /> <activity ...> ... <!-- Launch activity as default from Android Studio --> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> <!-- Launch activity automatically on boot --> <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>
" /> <activity ...> ... <!-- Launch activity as default from Android Studio --> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> <!-- Launch activity automatically on boot --> <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>
" /> <activity ...> ... <!-- Launch activity as default from Android Studio --> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> <!-- Launch activity automatically on boot --> <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>
ã¹ããã3ïŒãã¿ã³
ã¯ããã¯ãã¿ã³ãæ¥ç¶ããŠã¿ãŸãããã¹ã¿ãŒãã¯ãæŒããããšããã«ã¡ã©ãã¯ã³ã·ã§ãããåããŸãã - åè·¯ãå®æããããã©ã³ãžã£ãŒãæŒãããŠããïŒããã¯åçŽãªã¡ã«ããºã ã§ãã 4ã€ã®æ¥ç¹ãæã€ãã¿ã³ã¯ãæ¥ç¶ã¬ãŒã«ã®2察ãå«ã¿ãŸãã ãã¬ãŒãéã®ééåŸã®æéã®éåžžã«å°ããæéã«è€æ°ã®ã¹ã€ããã³ã°ãããªã¬ããããã€ãã®ãã€ã¯ããã¿ã³ããããŸãã ããã¯ãããŠã³ã¹ãšåŒã°ããŠããŸãã 詳现æ å ±ãã¿ã³ ã
ãã¿ã³ã¯1kã®æµæãšãã¬ããããŒããä»ããŠæ¥ç¶ãããŠããŸãã æµæåšã®äžã§è¿·åã«ããªãããã«ããããã«åœŒãã®æ³šæãæãã«ã©ãŒã³ãŒãã£ã³ã° ã ã®ã¯ã詳现æ¥ç¶ããã»ã¹ããã€ã³ãããªãããã«ããŸãããã ãã ããã³ã©ãºããªãŒããã®å°ãé«ããšèšããããåè·¯ããããã³ã°ããŸãã
ãã¿ã³ã¯äœ¿çšçµ±åããæºåãã§ããŠããã©ã€ããã§ã«èæ ®ã«ããŠã³ã¹ã®å¹æãåããã è¿œå ã®äŸåé¢ä¿
dependencies { ... compile 'com.google.android.things.contrib:driver-button:0.3' ... }
0.3' dependencies { ... compile 'com.google.android.things.contrib:driver-button:0.3' ... }
ãã¿ã³ã®ã¯ã©ã¹ã©ãããŒãæžããŸãã ãããããã©ãããŒã®å®æœãéããŠãããã¯å°ãéå°ã«èŠãããããããŸãããããã®ãããªæ¹æ³ã¯ãæã ã¯ãã¿ã³ã®ãã©ã€ãã³ãŒãã§ã®åäœãã«ãã»ã«åããç¬èªã®ã€ã³ã¿ãã§ãŒã¹ãšã®å¯Ÿè©±ãäœæããããšãã§ããŸãã
import com.google.android.things.contrib.driver.button.Button; public class ButtonWrapper { private @Nullable Button mButton; private @Nullable OnButtonClickListener mOnButtonClickListener; public ButtonWrapper(final String gpioPin) { try { mButton = new Button(gpioPin, Button.LogicState.PRESSED_WHEN_HIGH); mButton.setOnButtonEventListener(new Button.OnButtonEventListener() { @Override public void onButtonEvent(Button button, boolean pressed) { if (pressed && mOnButtonClickListener != null) { mOnButtonClickListener.onClick(); } } }); } catch (IOException e) { e.printStackTrace(); } } public void setOnButtonClickListener(@Nullable final OnButtonClickListener listener) { mOnButtonClickListener = listener; } public void onDestroy() { if (mButton == null) { return; } try { mButton.close(); } catch (IOException e) { e.printStackTrace(); } finally { mButton = null; } } public interface OnButtonClickListener { public void onClick(); } }
ïŒã import com.google.android.things.contrib.driver.button.Button; public class ButtonWrapper { private @Nullable Button mButton; private @Nullable OnButtonClickListener mOnButtonClickListener; public ButtonWrapper(final String gpioPin) { try { mButton = new Button(gpioPin, Button.LogicState.PRESSED_WHEN_HIGH); mButton.setOnButtonEventListener(new Button.OnButtonEventListener() { @Override public void onButtonEvent(Button button, boolean pressed) { if (pressed && mOnButtonClickListener != null) { mOnButtonClickListener.onClick(); } } }); } catch (IOException e) { e.printStackTrace(); } } public void setOnButtonClickListener(@Nullable final OnButtonClickListener listener) { mOnButtonClickListener = listener; } public void onDestroy() { if (mButton == null) { return; } try { mButton.close(); } catch (IOException e) { e.printStackTrace(); } finally { mButton = null; } } public interface OnButtonClickListener { public void onClick(); } }
æŒãããŸããïŒ{ import com.google.android.things.contrib.driver.button.Button; public class ButtonWrapper { private @Nullable Button mButton; private @Nullable OnButtonClickListener mOnButtonClickListener; public ButtonWrapper(final String gpioPin) { try { mButton = new Button(gpioPin, Button.LogicState.PRESSED_WHEN_HIGH); mButton.setOnButtonEventListener(new Button.OnButtonEventListener() { @Override public void onButtonEvent(Button button, boolean pressed) { if (pressed && mOnButtonClickListener != null) { mOnButtonClickListener.onClick(); } } }); } catch (IOException e) { e.printStackTrace(); } } public void setOnButtonClickListener(@Nullable final OnButtonClickListener listener) { mOnButtonClickListener = listener; } public void onDestroy() { if (mButton == null) { return; } try { mButton.close(); } catch (IOException e) { e.printStackTrace(); } finally { mButton = null; } } public interface OnButtonClickListener { public void onClick(); } }
ïŒ{ import com.google.android.things.contrib.driver.button.Button; public class ButtonWrapper { private @Nullable Button mButton; private @Nullable OnButtonClickListener mOnButtonClickListener; public ButtonWrapper(final String gpioPin) { try { mButton = new Button(gpioPin, Button.LogicState.PRESSED_WHEN_HIGH); mButton.setOnButtonEventListener(new Button.OnButtonEventListener() { @Override public void onButtonEvent(Button button, boolean pressed) { if (pressed && mOnButtonClickListener != null) { mOnButtonClickListener.onClick(); } } }); } catch (IOException e) { e.printStackTrace(); } } public void setOnButtonClickListener(@Nullable final OnButtonClickListener listener) { mOnButtonClickListener = listener; } public void onDestroy() { if (mButton == null) { return; } try { mButton.close(); } catch (IOException e) { e.printStackTrace(); } finally { mButton = null; } } public interface OnButtonClickListener { public void onClick(); } }
ïŒ{ import com.google.android.things.contrib.driver.button.Button; public class ButtonWrapper { private @Nullable Button mButton; private @Nullable OnButtonClickListener mOnButtonClickListener; public ButtonWrapper(final String gpioPin) { try { mButton = new Button(gpioPin, Button.LogicState.PRESSED_WHEN_HIGH); mButton.setOnButtonEventListener(new Button.OnButtonEventListener() { @Override public void onButtonEvent(Button button, boolean pressed) { if (pressed && mOnButtonClickListener != null) { mOnButtonClickListener.onClick(); } } }); } catch (IOException e) { e.printStackTrace(); } } public void setOnButtonClickListener(@Nullable final OnButtonClickListener listener) { mOnButtonClickListener = listener; } public void onDestroy() { if (mButton == null) { return; } try { mButton.close(); } catch (IOException e) { e.printStackTrace(); } finally { mButton = null; } } public interface OnButtonClickListener { public void onClick(); } }
ç§ãã¡ã¯ãç§ãã¡ã®æŽ»åã§ããã®ã©ãããŒã䜿çšããŠããŸãã ã¡ããã©ãããåè·¯ã«æ¥ç¶ãããŠããã©ãºããªãŒPI3äžã®ãªããžã§ã¯ãããŒåGPIOããŒãïŒãBCM4ãïŒãã®ã³ã³ã¹ãã©ã¯ã¿ãäžããŸãã
public class MainActivity extends Activity { private static final String GPIO_PIN_BUTTON = "BCM4"; private ButtonWrapper mButtonWrapper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... mButtonWrapper = new ButtonWrapper(GPIO_PIN_BUTTON); mButtonWrapper.setOnButtonClickListener(new ButtonWrapper.OnButtonClickListener() { @Override public void onClick() { Timber.d("BUTTON WAS CLICKED"); startTakingImage(); } }); ... } @Override protected void onDestroy() { super.onDestroy(); ... mButtonWrapper.onDestroy(); ... } private void startTakingImage() { // TODO take photo ... } }
ãã public class MainActivity extends Activity { private static final String GPIO_PIN_BUTTON = "BCM4"; private ButtonWrapper mButtonWrapper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... mButtonWrapper = new ButtonWrapper(GPIO_PIN_BUTTON); mButtonWrapper.setOnButtonClickListener(new ButtonWrapper.OnButtonClickListener() { @Override public void onClick() { Timber.d("BUTTON WAS CLICKED"); startTakingImage(); } }); ... } @Override protected void onDestroy() { super.onDestroy(); ... mButtonWrapper.onDestroy(); ... } private void startTakingImage() { // TODO take photo ... } }
; public class MainActivity extends Activity { private static final String GPIO_PIN_BUTTON = "BCM4"; private ButtonWrapper mButtonWrapper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... mButtonWrapper = new ButtonWrapper(GPIO_PIN_BUTTON); mButtonWrapper.setOnButtonClickListener(new ButtonWrapper.OnButtonClickListener() { @Override public void onClick() { Timber.d("BUTTON WAS CLICKED"); startTakingImage(); } }); ... } @Override protected void onDestroy() { super.onDestroy(); ... mButtonWrapper.onDestroy(); ... } private void startTakingImage() { // TODO take photo ... } }
ã¹ããã4ïŒã«ã¡ã©
ç§ãã¡ã¯ãã«ã¡ã©ã®äœ¿çšNOIRã«ã¡ã©V2ã ã ããã$ 45ããªãã¯ç§ãã¡ã®ãããžã§ã¯ãã®ããã«ååãªç¹æ§ãåŸãããŸãã
- æ倧解å床ïŒ8 MïŒ3280Ã2464ïŒã
- ãããªãã©ãŒãããããµããŒãïŒ1080ïŒ30fpsã®ïŒã720PïŒ60fpsã®ïŒã640Ã480PïŒ90fpsïŒãã
- æ¶è²»é»åïŒ250ããªã¢ã³ãã¢
ã«ã¡ã©ã¯ããã©ããã±ãŒãã«CSIãããªå ¥åïŒã«ã¡ã©ã·ãªã¢ã«ã€ã³ã¿ãã§ãŒã¹ïŒãä»ããŠå¶åŸ¡åè·¯åºæ¿ã«æ¥ç¶ãããŠããŸãã ãã®æ¹æ³ã¯ãUSBãæ¥ç¶ããããã®åæ§ã®ãã£ã³ãã«æ¯ã¹CPUã®è² æ ãæžå°ãããŸãã
ã䜿ãã®ã«ã¡ã©ãšã補åããããæã£ãŠããå¿ èŠãããããšãèŠä»¶ã䜿çšããããã«ãããã§ã¹ããè¿œå ããŸãã å±éºãªæš©éãå«ããå¿ ãèš±å¯ãè¿œå ãããããã¹ãŠã®ã¢ã¯ã»ã¹æš©ã«åæããããã¯ããªããïŒã¢ããªã±ãŒã·ã§ã³ãåã€ã³ã¹ããŒã«ããåŸãæ°ããªpermishenaãè¿œå ãããšãå®å šã«ããã€ã¹ãåèµ·åããå¿ èŠããããŸããšããæ¢ç¥ã®åé¡ãããïŒã¢ããªã±ãŒã·ã§ã³ã®ã€ã³ã¹ããŒã«æã«èªåçã«ãªããŸãã
<uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera.autofocus" />
"android.permission.CAMERA" /> <uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera.autofocus" />
"android.hardware.camera" /> <uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera.autofocus" />
ããã«ã«ã¡ã©ãæ¥ç¶ããã«ã¯ãã³ãŒãã®ãã®éšåã®åºæºã§çŽ æŽãããèšäºãæžãããã§ãã ã§ããããèªåã§èªãã§ãã ããããã®ãªã³ã¯å ¬åŒãµã€ãã§ã ã³ãŒãã§ã¯ãã«ã¡ã©ã®èšå®ãèšå®ããŸãã ç§ãã¡ã¯ããã¹ãŠã®é»æºã䜿çšããŠã480x320ã®è§£å床ãéžæããŸããã§ããã
ã¹ããã5ïŒLED
LED - é»æµãæµããããšã«ãã£ãŠç¹ç¯åãã€ãªãŒããã 飜ååŸã圌èªèº«ã®æµæãéåžžã«å°ããã§ãã ããªãã¯ãLEDãééããé»æµããŸãã¯ã¡ããã©æåŸã®ææãå¶éããå¿ èŠãªæµæãæ¥ç¶ããå Žåã 詳现ãLED
ç§ãã¡ã¯ãç°ãªãè²ã®3åã®LEDã䜿çšããŸãã
- ã€ãšããŒïŒ
BCM20
ïŒ -éçºè ã«ãã£ãŠæå®ãããæéééã延é·ããäœæ¥ã®éå§ã®ã€ã³ãžã±ãŒã¿ã - ïŒç·è²
BCM21
ïŒ -ããã°ã©ã ãæ£åžžããŒã¿ããŒã¹ããé¡ãæ€åºããŸãã - ïŒèµ€
BCM16
ïŒ -ããã°ã©ã ã¯ãæå®ãããæéééã®éã«é¡ãèªèããŸããã
代ããã«3ã€ã®ã¢ãã¯ããŒã ã®ã·ã³ã°ã«äžè²ã®LEDã䜿çšããããšãã§ããŸãã ç§ãã¡ã¯ããããæå ã«ãã£ããšããäºå®ã楜ãã¿ãŸããã å³ã«ç€ºãããã«ã1ãªãŒã ã®æµæã䜿çšããŠãæã ã¯ããã¬ããããŒããä»ããŠäº€äºã«ç§éã®LEDãæ¥ç¶ããŸãã
LEDã§äœ¿çšããããã®ã©ãããŒå®è£
ããå Žåã¯PeripheralManagerService
ãããªãã®GPIOã€ã³ã¿ãã§ãŒã¹ãžã®ã¢ã¯ã»ã¹ãæäŸãããµãŒãã¹ãã ãªãŒãã³ãªæ¥ç¶ãšä¿¡å·äŒéã®ããã®configureãããã ããªãã¯æœè±¡ã¯ã©ã¹ã®å®è£
ãèŠãã°æ®å¿µãªããã com.google.android.things.pio.Gpio
ãæã
ã¯èŠãããšãã§ããã³ãŒã«çºçãããããšãã§ããã»ãŒãã¹ãŠã®æ¹æ³java.io.IOException
ã ç°¡åã«ããããã«ããã¹ãŠã®é衚瀺try-catch
ç§ãã¡ã®ã©ãããŒã§åŒãã
public class LedWrapper { private @Nullable Gpio mGpio; public LedWrapper(String gpioPin) { try { PeripheralManagerService service = new PeripheralManagerService(); mGpio = service.openGpio(gpioPin); mGpio.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW); } catch (IOException e) { e.printStackTrace(); } } public void turnOn() { if (mGpio == null) { return; } try { mGpio.setValue(true); } catch (IOException e) { e.printStackTrace(); } } public void turnOff() { if (mGpio == null) { return; } try { mGpio.setValue(false); } catch (IOException e) { e.printStackTrace(); } } public void onDestroy() { try { mGpio.close(); } catch (IOException e) { e.printStackTrace(); } finally { mGpio = null; } } }
åå¥ã«åLEDã®ããã®ç§ãã¡ã®æŽ»åã§ãããImplementiruemã
public class MainActivity extends Activity { private final static String GPIO_PIN_LED_GREEN = âBCM21â; private LedWrapper mLedWrapper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... mLedWrapper = new LedWrapper(GPIO_PIN_LED_GREEN); mLedWrapper.turnOff(); ... } private void turnOn() { mLedWrapper.turnOn(); } @Override protected void onDestroy() { super.onDestroy(); ... mLedWrapper.onDestroy(); ... } }
ãã public class MainActivity extends Activity { private final static String GPIO_PIN_LED_GREEN = âBCM21â; private LedWrapper mLedWrapper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... mLedWrapper = new LedWrapper(GPIO_PIN_LED_GREEN); mLedWrapper.turnOff(); ... } private void turnOn() { mLedWrapper.turnOn(); } @Override protected void onDestroy() { super.onDestroy(); ... mLedWrapper.onDestroy(); ... } }
ã¹ããã6ïŒã¢ãŒã·ã§ã³ã»ã³ãµãŒ
ãã³ã«ãç§ãã¡ã¯ãã¢ã«è¿ã¥ããšéå±ããã®ãã¢ãã«ãã®ããã«ããã¿ã³ãæŒããŠãã ããã æã ã¯ãäžå¿ èŠãªè¡åãããåœç€Ÿã®ãªãã£ã¹ã®ã客æ§ãåãé€ãããç·ãå¯äžã®ãã¢ã«æ¥ããŸã§ããå®å šã«ãã¢ãéãããã£ãã§ãã ã ããæã ã¯ãã·ã¹ãã å šäœã®éå§ã®ããã®äž»ãªããªã¬ãšããŠãã¢ãŒã·ã§ã³ã»ã³ãµãŒã䜿çšããããšã«ããŸããã ãããã®å Žåã«ãããŠããæ®ããã¿ã³ã§ãããªã©ã®æ©èœãè€è£œããŸãã 詳现ã¢ãŒã·ã§ã³ã»ã³ãµãŒ ã
ä»ããŠã¢ãŒã·ã§ã³ã»ã³ãµãŒãæ¥ç¶BCM6
以äžã®ã¹ããŒã ã«åŸã£ãŠãã³ã
public class MotionWrapper { private @Nullable Gpio mGpio; private @Nullable MotionEventListener mMotionEventListener; public MotionWrapper(String gpioPin) { try { mGpio = new PeripheralManagerService().openGpio(gpioPin); } catch (IOException e) { e.printStackTrace(); } } public void setMotionEventListener(@Nullable final MotionEventListener listener) { mMotionEventListener = listener; } public void startup() { try { mGpio.setDirection(Gpio.DIRECTION_IN); mGpio.setActiveType(Gpio.ACTIVE_HIGH); mGpio.setEdgeTriggerType(Gpio.EDGE_RISING); mGpio.registerGpioCallback(mCallback); } catch (IOException e) { e.printStackTrace(); } } public void shutdown() { if (mGpio == null) { return; } try { mGpio.unregisterGpioCallback(mCallback); mGpio.close(); } catch (IOException e) { e.printStackTrace(); } } public void onDestroy() { try { mGpio.close(); } catch (IOException e) { e.printStackTrace(); } finally { mGpio = null; } } private final GpioCallback mCallback = new GpioCallback() { @Override public boolean onGpioEdge(Gpio gpio) { if (mMotionEventListener != null) { mMotionEventListener.onMovement(); } return true; } }; public interface MotionEventListener { void onMovement(); } }
gpioPinïŒ; public class MotionWrapper { private @Nullable Gpio mGpio; private @Nullable MotionEventListener mMotionEventListener; public MotionWrapper(String gpioPin) { try { mGpio = new PeripheralManagerService().openGpio(gpioPin); } catch (IOException e) { e.printStackTrace(); } } public void setMotionEventListener(@Nullable final MotionEventListener listener) { mMotionEventListener = listener; } public void startup() { try { mGpio.setDirection(Gpio.DIRECTION_IN); mGpio.setActiveType(Gpio.ACTIVE_HIGH); mGpio.setEdgeTriggerType(Gpio.EDGE_RISING); mGpio.registerGpioCallback(mCallback); } catch (IOException e) { e.printStackTrace(); } } public void shutdown() { if (mGpio == null) { return; } try { mGpio.unregisterGpioCallback(mCallback); mGpio.close(); } catch (IOException e) { e.printStackTrace(); } } public void onDestroy() { try { mGpio.close(); } catch (IOException e) { e.printStackTrace(); } finally { mGpio = null; } } private final GpioCallback mCallback = new GpioCallback() { @Override public boolean onGpioEdge(Gpio gpio) { if (mMotionEventListener != null) { mMotionEventListener.onMovement(); } return true; } }; public interface MotionEventListener { void onMovement(); } }
ïŒ{ public class MotionWrapper { private @Nullable Gpio mGpio; private @Nullable MotionEventListener mMotionEventListener; public MotionWrapper(String gpioPin) { try { mGpio = new PeripheralManagerService().openGpio(gpioPin); } catch (IOException e) { e.printStackTrace(); } } public void setMotionEventListener(@Nullable final MotionEventListener listener) { mMotionEventListener = listener; } public void startup() { try { mGpio.setDirection(Gpio.DIRECTION_IN); mGpio.setActiveType(Gpio.ACTIVE_HIGH); mGpio.setEdgeTriggerType(Gpio.EDGE_RISING); mGpio.registerGpioCallback(mCallback); } catch (IOException e) { e.printStackTrace(); } } public void shutdown() { if (mGpio == null) { return; } try { mGpio.unregisterGpioCallback(mCallback); mGpio.close(); } catch (IOException e) { e.printStackTrace(); } } public void onDestroy() { try { mGpio.close(); } catch (IOException e) { e.printStackTrace(); } finally { mGpio = null; } } private final GpioCallback mCallback = new GpioCallback() { @Override public boolean onGpioEdge(Gpio gpio) { if (mMotionEventListener != null) { mMotionEventListener.onMovement(); } return true; } }; public interface MotionEventListener { void onMovement(); } }
ïŒ{ public class MotionWrapper { private @Nullable Gpio mGpio; private @Nullable MotionEventListener mMotionEventListener; public MotionWrapper(String gpioPin) { try { mGpio = new PeripheralManagerService().openGpio(gpioPin); } catch (IOException e) { e.printStackTrace(); } } public void setMotionEventListener(@Nullable final MotionEventListener listener) { mMotionEventListener = listener; } public void startup() { try { mGpio.setDirection(Gpio.DIRECTION_IN); mGpio.setActiveType(Gpio.ACTIVE_HIGH); mGpio.setEdgeTriggerType(Gpio.EDGE_RISING); mGpio.registerGpioCallback(mCallback); } catch (IOException e) { e.printStackTrace(); } } public void shutdown() { if (mGpio == null) { return; } try { mGpio.unregisterGpioCallback(mCallback); mGpio.close(); } catch (IOException e) { e.printStackTrace(); } } public void onDestroy() { try { mGpio.close(); } catch (IOException e) { e.printStackTrace(); } finally { mGpio = null; } } private final GpioCallback mCallback = new GpioCallback() { @Override public boolean onGpioEdge(Gpio gpio) { if (mMotionEventListener != null) { mMotionEventListener.onMovement(); } return true; } }; public interface MotionEventListener { void onMovement(); } }
ãããªãã¯ã¯ã©ã¹MainActivityã¯{ã¢ã¯ãã£ããã£ãæ¡åŒµããŸã
private static final String GPIO_PIN_MOTION_SENSOR = "BCM6"; private MotionWrapper mMotionWrapper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... mMotionWrapper = new MotionWrapper(GPIO_PIN_MOTION_SENSOR); mMotionWrapper.setMotionEventListener(new MotionWrapper.MotionEventListener() { @Override public void onMovement() { startTakingPhotos(); } }); mMotionWrapper.startup(); ...
ãã private static final String GPIO_PIN_MOTION_SENSOR = "BCM6"; private MotionWrapper mMotionWrapper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... mMotionWrapper = new MotionWrapper(GPIO_PIN_MOTION_SENSOR); mMotionWrapper.setMotionEventListener(new MotionWrapper.MotionEventListener() { @Override public void onMovement() { startTakingPhotos(); } }); mMotionWrapper.startup(); ...
}
@Override protected void onDestroy() { super.onDestroy(); ... mMotionWrapper.shutdown(); mMotionWrapper.onDestroy(); ... } private void startTakingPhotos() { ... }
}
ã¹ããã7ïŒãµãŒã
ãµãŒãã¯ãç§ãã¡ã®ããã€ã¹ã«ãããåºæ¬çãªæ©æ¢°çãªäœæ¥ã«ãªããŸãã ããã¯åœŒããåºå軞180床å転ãããšããªãŒããŒã«ã«ãŒãããããããŸããã ããã«è©³ããæ å ±ã«ã€ããŠãµãŒã ã
ç§ãã¡ã¯åã³ããã§ã«äœ¿çšããŠæ¢åã®ãã©ã€ãæã
ã¯ã©ãããŒãèšè¿°ããŠããããã è¿œå app/build.gradle
äŸåæ§ã
dependencies { ... compile 'com.google.android.things.contrib:driver-pwmservo:0.2' ... }
0.2' dependencies { ... compile 'com.google.android.things.contrib:driver-pwmservo:0.2' ... }
ãã©ã€ããä»ããŠæ¥ç¶ãããŠããã€ã³ã¿ãã§ãŒã¹PWM PWM1
äžèšã¹ããŒã ã«åŸã£ãŠã 䜿çšãPWM
ã«ãã以åã®ã±ãŒã¹ãšã¯ç°ãªãã代ããã«ãåã«ãã€ããªãã«ã¹ã®ãå¶åŸ¡ä¿¡å·ãä»ããŠç¹å®ã®å€ãéä¿¡ããå¿
èŠãããããšããäºå®ã®ããã«ã€ã³ã¿ãŒãã§ã€ã¹ãã å¶åŸ¡ä¿¡å· - äžå®ã®åšæ³¢æ°ãšå¯å€å¹
ã®ãã«ã¹ã ãµãŒãã¯ãåºå軞ã®å転ã®ç¹å®ã®è§åºŠã«å€æãPWMå
¥åä¿¡å·å¹
ãã«ã¹ã䜿çšããŸãã
public class ServoWrapper { private static final float ANGLE_CLOSE = 0f; private static final float ANGLE_OPEN = 180f; private Servo mServo; private Handler mHandler = new Handler(); public ServoWrapper(final String gpioPin) { try { mServo = new Servo(gpioPin); mServo.setAngleRange(ANGLE_CLOSE, ANGLE_OPEN); mServo.setEnabled(true); } catch (IOException e) { e.printStackTrace(); } } public void open(final long delayMillis) { try { mServo.setAngle(ANGLE_OPEN); } catch (IOException e) { e.printStackTrace(); } mHandler.removeCallbacks(mMoveServoRunnable); if (delayMillis > 0) { mHandler.postDelayed(mMoveServoRunnable, delayMillis); } } public void close() { if (mServo == null) { return; } try { mServo.setAngle(ANGLE_CLOSE); } catch (IOException e) { e.printStackTrace(); } } public void onDestroy() { mHandler.removeCallbacks(mMoveServoRunnable); mMoveServoRunnable = null; if (mServo != null) { try { mServo.close(); } catch (IOException e) { e.printStackTrace(); } finally { mServo = null; } } } private Runnable mMoveServoRunnable = new Runnable() { @Override public void run() { mHandler.removeCallbacks(this); close(); } }; }
; public class ServoWrapper { private static final float ANGLE_CLOSE = 0f; private static final float ANGLE_OPEN = 180f; private Servo mServo; private Handler mHandler = new Handler(); public ServoWrapper(final String gpioPin) { try { mServo = new Servo(gpioPin); mServo.setAngleRange(ANGLE_CLOSE, ANGLE_OPEN); mServo.setEnabled(true); } catch (IOException e) { e.printStackTrace(); } } public void open(final long delayMillis) { try { mServo.setAngle(ANGLE_OPEN); } catch (IOException e) { e.printStackTrace(); } mHandler.removeCallbacks(mMoveServoRunnable); if (delayMillis > 0) { mHandler.postDelayed(mMoveServoRunnable, delayMillis); } } public void close() { if (mServo == null) { return; } try { mServo.setAngle(ANGLE_CLOSE); } catch (IOException e) { e.printStackTrace(); } } public void onDestroy() { mHandler.removeCallbacks(mMoveServoRunnable); mMoveServoRunnable = null; if (mServo != null) { try { mServo.close(); } catch (IOException e) { e.printStackTrace(); } finally { mServo = null; } } } private Runnable mMoveServoRunnable = new Runnable() { @Override public void run() { mHandler.removeCallbacks(this); close(); } }; }
{ public class ServoWrapper { private static final float ANGLE_CLOSE = 0f; private static final float ANGLE_OPEN = 180f; private Servo mServo; private Handler mHandler = new Handler(); public ServoWrapper(final String gpioPin) { try { mServo = new Servo(gpioPin); mServo.setAngleRange(ANGLE_CLOSE, ANGLE_OPEN); mServo.setEnabled(true); } catch (IOException e) { e.printStackTrace(); } } public void open(final long delayMillis) { try { mServo.setAngle(ANGLE_OPEN); } catch (IOException e) { e.printStackTrace(); } mHandler.removeCallbacks(mMoveServoRunnable); if (delayMillis > 0) { mHandler.postDelayed(mMoveServoRunnable, delayMillis); } } public void close() { if (mServo == null) { return; } try { mServo.setAngle(ANGLE_CLOSE); } catch (IOException e) { e.printStackTrace(); } } public void onDestroy() { mHandler.removeCallbacks(mMoveServoRunnable); mMoveServoRunnable = null; if (mServo != null) { try { mServo.close(); } catch (IOException e) { e.printStackTrace(); } finally { mServo = null; } } } private Runnable mMoveServoRunnable = new Runnable() { @Override public void run() { mHandler.removeCallbacks(this); close(); } }; }
{ public class ServoWrapper { private static final float ANGLE_CLOSE = 0f; private static final float ANGLE_OPEN = 180f; private Servo mServo; private Handler mHandler = new Handler(); public ServoWrapper(final String gpioPin) { try { mServo = new Servo(gpioPin); mServo.setAngleRange(ANGLE_CLOSE, ANGLE_OPEN); mServo.setEnabled(true); } catch (IOException e) { e.printStackTrace(); } } public void open(final long delayMillis) { try { mServo.setAngle(ANGLE_OPEN); } catch (IOException e) { e.printStackTrace(); } mHandler.removeCallbacks(mMoveServoRunnable); if (delayMillis > 0) { mHandler.postDelayed(mMoveServoRunnable, delayMillis); } } public void close() { if (mServo == null) { return; } try { mServo.setAngle(ANGLE_CLOSE); } catch (IOException e) { e.printStackTrace(); } } public void onDestroy() { mHandler.removeCallbacks(mMoveServoRunnable); mMoveServoRunnable = null; if (mServo != null) { try { mServo.close(); } catch (IOException e) { e.printStackTrace(); } finally { mServo = null; } } } private Runnable mMoveServoRunnable = new Runnable() { @Override public void run() { mHandler.removeCallbacks(this); close(); } }; }
ãããªãã¯ã¯ã©ã¹MainActivityã¯{ã¢ã¯ãã£ããã£ãæ¡åŒµããŸã
private static final String GPIO_PIN_SERVO = "PWM1"; private ServoWrapper mServoWrapper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... mServoWrapper = new ServoWrapper(GPIO_PIN_SERVO); ...
ãã private static final String GPIO_PIN_SERVO = "PWM1"; private ServoWrapper mServoWrapper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... mServoWrapper = new ServoWrapper(GPIO_PIN_SERVO); ...
}
private void openDoor() { ... mServoWrapper.open(DELAY_SERVO_MS); ... } @Override protected void onDestroy() { super.onDestroy(); ... mServoWrapper.onDestroy(); ... }
}
ã¹ããã8ïŒãã©ãã¬ãžã¹ã¿
å€éã®äœæ¥ã§ããããåä¿¡ç»åã®ç¡æå³ãªåã§ããé¡ãæ€åºããããšãããå°é£ã§ãã ãã®æ段ã¯ãã·ã¹ãã ãäžæçã«ç¡å¹ã«ããããšãã§ããŸãã å äŸåæ§æµæïŒLDRïŒ - ãã©ãã¬ãžã¹ã¿ãçšããå ã»ã³ãµãšããŠããã®ç®çã®ããã«ã 詳现ã«ã€ããŠã¯photoresisto ã
ãã©ãã¬ãžã¹ã¿ãé©åãªããŒãã©ã€ãã§åäœããããã«ãåè¿°ããããã«ã èªç¶ãšã¡ã«ããã¯ãæ¬åœã«äžèŽåãã®ã§ãããã¯ãè«ççã§ãã app/build.gradle
ãæ¢ã«ã©ã€ãã©ãªã«æ¥ç¶ããå¿
èŠããããŸãã
dependencies { ... compile 'com.google.android.things.contrib:driver-button:0.3' ... }
0.3' dependencies { ... compile 'com.google.android.things.contrib:driver-button:0.3' ... }
ãã¬ããããŒãåæ§ã®ã¹ããŒã ãã¿ã³æ¥ç¶ãžã®æ¥ç¶ã å¯äžã®éãã¯ã10ãªãŒã ã®æµæã䜿çšããããšã§ãã æã
ã¯ãããŒã䜿çšBCM25
ã
é¡äŒŒæ§ã«ãããããããæã ã¯åœŒã®ããã«å¥ã ã®ã©ãããŒãæžãããšãã§ããŸãã
public class BrightrWrapper { private @Nullable Button mLightDetector; private @Nullable OnLightStateChangeListener mOnLightStateChangeListener; public BrightrWrapper(final String gpioPin) { try { mLightDetector = new Button(gpioPin, Button.LogicState.PRESSED_WHEN_HIGH); mLightDetector.setOnButtonEventListener(new Button.OnButtonEventListener() { @Override public void onButtonEvent(Button button, boolean isLighted) { if (mOnLightStateChangeListener != null) { mOnLightStateChangeListener.onLightStateChange(isLighted); } } }); } catch (IOException e) { e.printStackTrace(); } } public void setOnLightStateListener(@Nullable final OnLightStateChangeListener listener) { mOnLightStateChangeListener = listener; } public void onDestroy() { if (mLightDetector == null) { return; } try { mLightDetector.close(); } catch (IOException e) { e.printStackTrace(); } } public interface OnLightStateChangeListener { public void onLightStateChange(boolean isLighted); } }
ïŒã public class BrightrWrapper { private @Nullable Button mLightDetector; private @Nullable OnLightStateChangeListener mOnLightStateChangeListener; public BrightrWrapper(final String gpioPin) { try { mLightDetector = new Button(gpioPin, Button.LogicState.PRESSED_WHEN_HIGH); mLightDetector.setOnButtonEventListener(new Button.OnButtonEventListener() { @Override public void onButtonEvent(Button button, boolean isLighted) { if (mOnLightStateChangeListener != null) { mOnLightStateChangeListener.onLightStateChange(isLighted); } } }); } catch (IOException e) { e.printStackTrace(); } } public void setOnLightStateListener(@Nullable final OnLightStateChangeListener listener) { mOnLightStateChangeListener = listener; } public void onDestroy() { if (mLightDetector == null) { return; } try { mLightDetector.close(); } catch (IOException e) { e.printStackTrace(); } } public interface OnLightStateChangeListener { public void onLightStateChange(boolean isLighted); } }
isLightedïŒ{ public class BrightrWrapper { private @Nullable Button mLightDetector; private @Nullable OnLightStateChangeListener mOnLightStateChangeListener; public BrightrWrapper(final String gpioPin) { try { mLightDetector = new Button(gpioPin, Button.LogicState.PRESSED_WHEN_HIGH); mLightDetector.setOnButtonEventListener(new Button.OnButtonEventListener() { @Override public void onButtonEvent(Button button, boolean isLighted) { if (mOnLightStateChangeListener != null) { mOnLightStateChangeListener.onLightStateChange(isLighted); } } }); } catch (IOException e) { e.printStackTrace(); } } public void setOnLightStateListener(@Nullable final OnLightStateChangeListener listener) { mOnLightStateChangeListener = listener; } public void onDestroy() { if (mLightDetector == null) { return; } try { mLightDetector.close(); } catch (IOException e) { e.printStackTrace(); } } public interface OnLightStateChangeListener { public void onLightStateChange(boolean isLighted); } }
ïŒ{ public class BrightrWrapper { private @Nullable Button mLightDetector; private @Nullable OnLightStateChangeListener mOnLightStateChangeListener; public BrightrWrapper(final String gpioPin) { try { mLightDetector = new Button(gpioPin, Button.LogicState.PRESSED_WHEN_HIGH); mLightDetector.setOnButtonEventListener(new Button.OnButtonEventListener() { @Override public void onButtonEvent(Button button, boolean isLighted) { if (mOnLightStateChangeListener != null) { mOnLightStateChangeListener.onLightStateChange(isLighted); } } }); } catch (IOException e) { e.printStackTrace(); } } public void setOnLightStateListener(@Nullable final OnLightStateChangeListener listener) { mOnLightStateChangeListener = listener; } public void onDestroy() { if (mLightDetector == null) { return; } try { mLightDetector.close(); } catch (IOException e) { e.printStackTrace(); } } public interface OnLightStateChangeListener { public void onLightStateChange(boolean isLighted); } }
public class MainActivity extends Activity { private static final String GPIO_PIN_LIGHT_DETECTOR = "BCM25"; private BrightrWrapper mBrightrWrapper; private boolean mIsTakePhotoAllowed = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... mBrightrWrapper = new BrightrWrapper(GPIO_PIN_LIGHT_DETECTOR); mBrightrWrapper.setOnLightStateListener(new BrightrWrapper.OnLightStateChangeListener() { @Override public void onLightStateChange(final boolean isLighted) { mIsTakePhotoAllowed = isLighted; handleLightState(); } }); ... } private void handleLightState() { if (mIsTakePhotoAllowed) { ... } else { ... } } @Override protected void onDestroy() { super.onDestroy(); ... mBrightrWrapper.onDestroy(); ... } }
ãã public class MainActivity extends Activity { private static final String GPIO_PIN_LIGHT_DETECTOR = "BCM25"; private BrightrWrapper mBrightrWrapper; private boolean mIsTakePhotoAllowed = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... mBrightrWrapper = new BrightrWrapper(GPIO_PIN_LIGHT_DETECTOR); mBrightrWrapper.setOnLightStateListener(new BrightrWrapper.OnLightStateChangeListener() { @Override public void onLightStateChange(final boolean isLighted) { mIsTakePhotoAllowed = isLighted; handleLightState(); } }); ... } private void handleLightState() { if (mIsTakePhotoAllowed) { ... } else { ... } } @Override protected void onDestroy() { super.onDestroy(); ... mBrightrWrapper.onDestroy(); ... } }
{ public class MainActivity extends Activity { private static final String GPIO_PIN_LIGHT_DETECTOR = "BCM25"; private BrightrWrapper mBrightrWrapper; private boolean mIsTakePhotoAllowed = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... mBrightrWrapper = new BrightrWrapper(GPIO_PIN_LIGHT_DETECTOR); mBrightrWrapper.setOnLightStateListener(new BrightrWrapper.OnLightStateChangeListener() { @Override public void onLightStateChange(final boolean isLighted) { mIsTakePhotoAllowed = isLighted; handleLightState(); } }); ... } private void handleLightState() { if (mIsTakePhotoAllowed) { ... } else { ... } } @Override protected void onDestroy() { super.onDestroy(); ... mBrightrWrapper.onDestroy(); ... } }
å®è£ ã®ãã¢ã³ã¹ãã¬ãŒã·ã§ã³
ãã¬ãçªçµãçæ°ã®æãã®ãã¹ãŠã®åé¡ãèŠçŽããç§ãã¡ã¯å·§ã¿ã«å€ãæºåž¯é»è©±ã®äžããç®±ã«ç§ãã¡ã®ãæªç©ããè©°ãã ãã®çµæãããªãã¯ããã®èšäºã®åé ã§èŠãããšãã§ããŸãã
åç»ãã¢
åé¡
質ã®æªãæ€åºåšãšã»ã³ãµãŒã ããªã¬ãŒãã©ããã¯ãå¿ èŠãªãšãã«èªçºãããããå¿ èŠãªããšãã ãµãŒãã¯ã¹ã¿ã³ãã€ã¢ãŒãã«ã¯ã©ãã¯ã«ã
ããªãã¯ã¢ãŒã·ã§ã³ã»ã³ãµãŒã®ååã«ç²ŸéããŠããå Žåãããªãã¯ãããæ©èœããªãããšã¬ã©ã¹ãéããŠèŠãããšãã§ããŸããã ã ããç§ã¯ãããããªã³ãã¢ãŠãããªããã°ãªããŸããã§ããã
ããªãã«ã®å åŽããç§ãã¡ã®ãã¶ã€ã³ãé 眮ããããšã«ããããã¹ãŠã®åçã¯ã²ã©ãæãªãããã°ã¬ãŒãžã³ã°ã ããã¯å ã®äžéšãåžåããããã«è¿ éã«åé¡ãçœãããã¯ã¹ã®è¡šé¢ããã®å ã®åå°ã§ãããçªã¬ã©ã¹ãçªç Žç¹°ãè¿ãããšãå®çŸããç§ãã¡ã¯ããã£ã³ãã®åšãã«çŽã®é»ã·ãŒãã貌ãä»ããŸãã
å°å·ãããåçããã®ä¿è·ãªãã
çµæ
以äžã®ããã®ãµã³ãã«ã³ãŒãGithubã« ã
é¢çœãããšããµã€ãã£ã³ã°ãªããã¬ã³ãã£ãè¥è ã ããã¯èå³æ·±ããããžã§ã¯ãã§ããããã®éçºã®ããã®ã¢ã€ãã¢ã¯ãŸã ããã«ãããŸãã äŸãã°ãå åŽãããã¢ãšã¯ãã«ãŒããéããŸãã å åŽãã圌女ã«æ¥ãŠèª°ã«ãæãéãããã« - ããªãã¯ãã®åé¡ã解決ããããšãã§ããŸãã ã³ã¡ã³ãã®äžã§ãåœç€Ÿã®ã¹ããŒãããã¯ã®ããªãã®ãªãã·ã§ã³ãå®äºããããšã瀺åããŠãã ããã 圌ãã¯ç§ãã¡ã®ãããªãã®ã§ããã°ãç§ãã¡ã¯ããããå®çŸããŸãã
ããªããç¥ã£ãŠããéçºã®IoTãåçåããããã®ãªãã·ã§ã³ã¯äœã§ããïŒ ã³ã¡ã³ãã§ããªãã®çµéšãå ±æããŠããŸãã
åºåãšããŠèè ãæãã€ãããšèªå®¶è£œãã¥ãŒã¹ãªãŒããŒç¹åå®æœããŠããçŽ æŽãããèšäºãå ±æããããªãBrailleBoxã匱ãAndroidã®ãã®ã«èŠãããã«ã ã«ãã¯ã¹ãšãããé³ãšããŠã¯ãŒã«ãšããŠå®è£ ãããŠããŸãã åªç§ãªãããžã§ã¯ããéŒèã
䟿å©ãªãªã³ã¯
- Androidã®ç©äº
- ã©ãºããªãŒPI3
- ãã©ã€ãïŒ1
- ãã©ã€ããŒïŒ2
- Mobilatorium
- ã¯ã©ãŠããã¢ãã«ã®æ§ç¯
- ã»ã³ãµãŒã¢ãŒã·ã§ã³ïŒ1
- ã»ã³ãµãŒã¢ãŒã·ã§ã³ïŒ2
- ã©ã®ããã«ã»ã³ãµãŒã¢ãŒã·ã§ã³äœå
- ãµãŒã
- LED
- ãã©ãã¬ãžã¹ã¿
- ãã©ãã¬ãžã¹ã¿ãµã³ãã«
- è¶ é³æ³¢ã»ã³ãµãŒ
- Rasberry3ãã³
- ã©ãºããªãŒãã€ã®GPIOãã³ã«ã€ããŠ
- GPIOãã³ã«ã€ããŠ
- PWMãã³ã«ã€ããŠ
- ãã¹ãŠã®Androidã®ããªãã®æåã®æžã蟌ã¿ç©äºã®ãã©ã€ã ã