2015年12月26日 星期六

[Arduino] Ex6_3:用紅外線遙控MeArm

Ex6_3:用紅外線遙控MeArm[2]
Ted Lee@CAVEDU
Jan. 1, 2016
88x31.png[4]

本文將介紹常見的家電紅外線遙控器來操作MeArm用四顆伺服馬達來模機器擬四軸機器手臂的動作。我們採用各個撃破演算法將題目拆解成兩大塊:紅外線搖控處理(Lab6_3_1)MeArm操作,再搭配三個實驗(Lab6_3_1-3)來細細品甞Arduino在自動控制上的威力!
本範例过関後,可獲得紅外線控制卡一張。

難易度:中

紅外線(Infrared)簡稱IR,是波長0.75-1000mm電磁波。它的應用方式為發送器(transmitter)發射紅外線電波信号(signal),接收器(receiver)接收到此信號後進行解碼(decoding)以控制它对應的電器裝置(devices),如家電用品(如冷氣、音響…)、電腦週邊裝置(如無線滑鼠、鍵盤…)都配有紅外線遙控器供我們遠控(remote control)操作。
以下的3個實驗Lab6_1-3將使用家電中常見的紅外線遙控器來控制MeArm以4顆伺服馬達(servo motors),用以模擬機器人手臂(robotic arms)的四軸運動。

材料:
  1. 紅外線遙控器一支
  2. 38kHz紅外線接收器(例如:TSOP38238、TSOP2438、TSOP4438、PNA4602、FM6038TH2、FM8038TM25DN)一顆
  3. MeArm一台
  4. 杜邦線若干條
  5. 麵包板一塊
  6. Arduino Uno R3一塊
  7. A-B型USB傳輸線一條

Lab6_3_1:拆解版(紅外線遙控器內建的通信協定能被IRremote函式庫正確识別)
Lab6_3_2:速配版(紅外線遙控器內建的通信協定能被IRremote函式庫正確识別+按正確解碼)
Lab6_3_3:不知是何姓名版(無法识別遙控器)

Lab6_1-3都援用了Ken Shirriff[2]寫的IRremote函式庫,下載後請放到Arduino的函數庫內──若程式編譯時出現和函式庫衝突,請參考葉難的解方(solution)

Windows:My Documents\Arduino\libraries\
Mac:Documents/Arduino/libraries
Linux:sketchbook內的libraries資料夾

Lab6_3_1:拆解版
這個實驗使用Mac專用遙控器38kHz紅外線接收器(接腳由左至右依順為Vout, GND, Vcc)。
程式碼:
#include <IRremote.h>

int RECV_PIN = 2;        //使用數位腳位2接收紅外線訊號
IRrecv irrecv(RECV_PIN); //初始化紅外線訊號輸入[3]
decode_results results;  //儲存訊號的結構

void setup() {
  Serial.begin(9600);
  irrecv.blink13(true); //設為true的話,當收到訊號時,腳位13的LED便會閃爍
  irrecv.enableIRIn();  //啟動接收
}

void loop() {
  if (irrecv.decode(&results)) {   //接收紅外線訊號並解碼
    Serial.print("results value is "); //輸出解碼後的資料
    Serial.print(results.value, HEX);
    Serial.print(", bits is ");
    Serial.print(results.bits);
    Serial.print(", decode_type is ");
    Serial.println(results.decode_type);
    irrecv.resume(); //準備接收下一個訊號
  }
}

Lab6_3_2:速配版
接線图:(.fzz
程式流程图如下(.vsdx):
程式碼:程式撰寫逻輯採演算法的各個撃破(divide and conquer)技巧,共可分為紅外線搖控處理(Lab6_3_1)MeArm操作兩段落,MeArm四軸的伺服馬達基本控制請参考Ex2_1,馬達與程式的對應為
不同遙控器的按鍵內碼需修改switch中各方向控制的case选項
#include <Servo.h>
#include <SoftwareSerial.h>
#include <IRremote.h>

const int irReceiverPin = 2; //紅外線接收器輸入訊號接在Arduino第2腳
IRrecv irrecv(irReceiverPin); //宣告IRrecv物件來接收紅外線訊號
decode_results results;

Servo servo_0, servo_1, servo_2, servo_3;

int i0 = 110;
int i1 = 150;
int i2 = 110;
int i3 = 130;
int i0max = 180;
int i0min = 0;
int i1max = 180;
int i1min = 90;
int i2max = 150;
int i2min = 50;
int i3max = 160;
int i3min = 100;

void setup() {
  Serial.begin(9600);
  irrecv.enableIRIn();
  delay(100); //等候信号穩定

  servo_0.attach(11); //buttom
  servo_0.write(i0);

  servo_1.attach(10); //right(面对爪子)
  servo_1.write(i1);

  servo_2.attach(9); //left
  servo_2.write(i2);

  servo_3.attach(5); //claw
  servo_3.write(i3);

  delay(100); //等候信號穩定
} //end of setup()

void loop() {
  if (irrecv.decode(&results)) {
    if (results.value != -1) {
      showIRProtocol(&results);   //顯示紅外線協定的種類
      Serial.println(results.value, HEX);

      switch (results.value) {
        case 0x38863BF8: //前進
          Serial.println("0x2F0:forward");

          if (i2 < i2max) i2++;
          break;
        case 0x38863BC4: //左轉
          Serial.println("0x2D0:turn left");

          if (i0 > i0min) i0++;
          break;
        case 0x38863BE4: //右轉
          Serial.println("0xCD0:turn right");

          if (i0 > i0min) i0--;
          break;
        case 0x38863BC8: //後退
          Serial.println("0xAF0:back");

          if (i2 >= i2min) i2--;
          break;
        case 0x38863BE8: //上移
          Serial.println("0x90:up");

          if (i1 < i1max) i1++;
          break;
        case 0x38863BD8: //下移
          Serial.println("0x890:down");

          if (i1 > i1min) i1--;
          break;
        case 0x38863BE0: //夾緊
          Serial.println("0x490:tight");

          if (i3 < i3max) i3++;
          break;
        case 0x38863BD0: //放鬆
          Serial.println("0xC90:loose");

          if (i3 > i3min) i3--;
          break;
      }//end of switch
    }//end of if

    irrecv.resume(); //Receive the next value

    servo_0.write(i0); //設定四軸初始的転角
    servo_1.write(i1);
    servo_2.write(i2);
    servo_3.write(i3);

    Serial.print("i0 pos ="); //顯示四軸的転角pos
    Serial.println(i0);
    Serial.print("i1 pos =");
    Serial.println(i1);
    Serial.print("i2 pos =");
    Serial.println(i2);
    Serial.print("i3 pos =");
    Serial.println(i3);
    delay(10); //等候信号穩定

    Serial.flush();
  } //end of if
} //end of loop()

void showIRProtocol(decode_results *results) {
  Serial.print("Protocol: ");

  //判斷紅外線協定種類
  switch (results->decode_type) {
    case NEC:
      Serial.print("NEC");
      break;
    case SONY:
      Serial.print("SONY");
      break;
    case RC5:
      Serial.print("RC5");
      break;
    case RC6:
      Serial.print("RC6");
      break;
    default:
      Serial.print("Unknown encoding");
  } //end of switch()

  //把紅外線編碼印到 Serial port
  Serial.print(", irCode: ");
  Serial.print(results->value, HEX);    // 紅外線編碼
  Serial.print(",  bits: ");
  Serial.println(results->bits);        // 紅外線編碼位元數
} //end of showIRProtocol()


以下為加上行号(line number)的程式碼,用以和流程圖相对照,並增進程式撰寫逻輯有更一步了解:
#include <Servo.h>
#include <SoftwareSerial.h>
#include <IRremote.h>

const int irReceiverPin = 2; //紅外線接收器輸入訊號接在Arduino第2腳
IRrecv irrecv(irReceiverPin); //宣告IRrecv物件來接收紅外線訊號
decode_results results;

Servo servo_0, servo_1, servo_2, servo_3;

int i0 = 110;
int i1 = 150;
int i2 = 110;
int i3 = 130;
int i0max = 180;
int i0min = 0;
int i1max = 180;
int i1min = 90;
int i2max = 150;
int i2min = 50;
int i3max = 160;
int i3min = 100;

void setup() {
  Serial.begin(9600);
  irrecv.enableIRIn();
  delay(100); //等候信号穩定

  servo_0.attach(11); //buttom
  servo_0.write(i0);

  servo_1.attach(10); //right(面对爪子)
  servo_1.write(i1);

  servo_2.attach(9); //left
  servo_2.write(i2);

  servo_3.attach(5); //claw
  servo_3.write(i3);

  delay(100); //等候信號穩定
} //end of setup()

void loop() {
  if (irrecv.decode(&results)) {
    if (results.value != -1) {
      showIRProtocol(&results);   //顯示紅外線協定的種類
      Serial.println(results.value, HEX);

      switch (results.value) {
        case 0x38863BF8: //前進
          Serial.println("0x2F0:forward");

          if (i2 < i2max) i2++;
          break;
        case 0x38863BC4: //左轉
          Serial.println("0x2D0:turn left");

          if (i0 > i0min) i0++;
          break;
        case 0x38863BE4: //右轉
          Serial.println("0xCD0:turn right");

          if (i0 > i0min) i0--;
          break;
        case 0x38863BC8: //後退
          Serial.println("0xAF0:back");

          if (i2 >= i2min) i2--;
          break;
        case 0x38863BE8: //上移
          Serial.println("0x90:up");

          if (i1 < i1max) i1++;
          break;
        case 0x38863BD8: //下移
          Serial.println("0x890:down");

          if (i1 > i1min) i1--;
          break;
        case 0x38863BE0: //夾緊
          Serial.println("0x490:tight");

          if (i3 < i3max) i3++;
          break;
        case 0x38863BD0: //放鬆
          Serial.println("0xC90:loose");

          if (i3 > i3min) i3--;
          break;
      }//end of switch
    }//end of if

    irrecv.resume(); //Receive the next value

    servo_0.write(i0); //設定四軸初始的転角
    servo_1.write(i1);
    servo_2.write(i2);
    servo_3.write(i3);

    Serial.print("i0 pos ="); //顯示四軸的転角pos
    Serial.println(i0);
    Serial.print("i1 pos =");
    Serial.println(i1);
    Serial.print("i2 pos =");
    Serial.println(i2);
    Serial.print("i3 pos =");
    Serial.println(i3);
    delay(10); //等候信号穩定

    Serial.flush();
  } //end of if
} //end of loop()

void showIRProtocol(decode_results *results) {
  Serial.print("Protocol: ");

  //判斷紅外線協定種類
  switch (results->decode_type) {
    case NEC:
      Serial.print("NEC");
      break;
    case SONY:
      Serial.print("SONY");
      break;
    case RC5:
      Serial.print("RC5");
      break;
    case RC6:
      Serial.print("RC6");
      break;
    default:
      Serial.print("Unknown encoding");
  } //end of switch()

  //把紅外線編碼印到 Serial port
  Serial.print(", irCode: ");
  Serial.print(results->value, HEX);    // 紅外線編碼
  Serial.print(",  bits: ");
  Serial.println(results->bits);        // 紅外線編碼位元數
} //end of showIRProtocol()

程式的執行畫面為:



















Lab6_3_3:不知是何姓名版
基於Lab6_3_2需要相互「速配」才能蹦出火花(在Arduino IDE的串列顯示器上僅會顯示Unknown encoding),我們找了Epson投影机搖控器來測試,程式修改處如粉紅色标示處,我們拿到了遙控器识別的副程式showIRProtocol(),並逐一將按鍵的內碼填到方向控制的switch选項內(例如:0xC1AA09F6表示前進)。


程式碼:
#include <Servo.h>
#include <SoftwareSerial.h>
#include <IRremote.h>

const int irReceiverPin = 2; //紅外線接收器輸入訊號接在Arduino第2腳
IRrecv irrecv(irReceiverPin); //宣告IRrecv物件來接收紅外線訊號
decode_results results;

Servo servo_0, servo_1, servo_2, servo_3;

int i0 = 110;
int i1 = 150;
int i2 = 110;
int i3 = 130;
int i0max = 180;
int i0min = 0;
int i1max = 180;
int i1min = 90;
int i2max = 150;
int i2min = 50;
int i3max = 160;
int i3min = 100;

void setup() {
  Serial.begin(9600);
  irrecv.enableIRIn();
  delay(100);

  servo_0.attach(11); //buttom
  servo_0.write(i0);

  servo_1.attach(10); //right(面对爪子)
  servo_1.write(i1);

  servo_2.attach(9); //left
  servo_2.write(i2);

  servo_3.attach(5); //claw
  servo_3.write(i3);

  delay(100);
} //end of setup()

void loop() {
  if (irrecv.decode(&results)) {
    Serial.print("Key code=");
    Serial.println(results.value, HEX);
   
    switch (results.value) {
      case 0xC1AA09F6: //前進
        Serial.println("0xC1AA09F6:forward");

        if (i2 < i2max) i2++;
        break;
      case 0x38863BC4: //左轉
        Serial.println("0x2D0:turn left");

        if (i0 > i0min) i0++;
        break;
      case 0x38863BE4: //右轉
        Serial.println("0xCD0:turn right");

        if (i0 > i0min) i0--;
        break;
       case 0x38863BC8: //後退
        Serial.println("0xAF0:back");

        if (i2 >= i2min) i2--;
        break;
      case 0x38863BE8: //上移
        Serial.println("0x90:up");

        if (i1 < i1max) i1++;
        break;
       case 0x38863BD8: //下移
        Serial.println("0x890:down");

        if (i1 > i1min) i1--;
        break;
      case 0x38863BE0: //夾緊
        Serial.println("0x490:tight");

        if (i3 < i3max) i3++;
        break;
      case 0x38863BD0: //放鬆
        Serial.println("0xC90:loose");

        if (i3 > i3min) i3--;
        break;
    }//end of switch

    irrecv.resume(); //Receive the next value

    servo_0.write(i0);
    servo_1.write(i1);
    servo_2.write(i2);
    servo_3.write(i3);

    Serial.print("i0 pos =");
    Serial.println(i0);
    Serial.print("i1 pos =");
    Serial.println(i1);
    Serial.print("i2 pos =");
    Serial.println(i2);
    Serial.print("i3 pos =");
    Serial.println(i3);
    delay(10);

    Serial.flush();
  } //end of if
} //end of loop()


執行結果:
Key code=C1AA09F6
0xC1AA09F6:forward
i0 pos =110
i1 pos =150
i2 pos =110
3 pos =130
Key code=C1AA31CE
i0 pos =110
i1 pos =150
i2 pos =110
i3 pos =130
Key code=C1AA29D6
i0 pos =110
i1 pos =150
i2 pos =110
i3 pos =130
Key code=C1AA0EF1
i0 pos =110
i1 pos =150
i2 pos =110
i3 pos =130
Key code=C1AA6E91
i0 pos =110
i1 pos =150
i2 pos =110
i3 pos =130
Key code=C1AA2ED1
i0 pos =110
i1 pos =150
i2 pos =110
i3 pos =130
Key code=C1AAFC03
i0 pos =110
i1 pos =150
i2 pos =110
i3 pos =130
Key code=C1AAC23D
i0 pos =110
i1 pos =150
i2 pos =110
i3 pos =130

参考資料:
  1. Arduino練習:紅外線傳送與接收,葉難,http://yehnan.blogspot.tw/2013/05/arduino.html。
  2. A Multi-Protocol Infrared Remote Library for the Arduino,Ken Shirriff,http://www.righto.com/2009/08/multi-protocol-infrared-remote-library.html.
  3. IRrecv Class,CY's Tech Talk,http://tech.cyborg5.com/irlib/docs/1-irlib-reference/1-1-receiver-classes/1-1-3-irrecv-class/.
  4. 六種授權條款,台灣創用CC計畫,http://creativecommons.tw/explore。

2015年12月1日 星期二

[Cloud Services:AWS] Internet Of Things (IoT)搭上Amazon Web Services(AWS)@AWS re:Invent 2015 Recap | 台灣

在這個盛会上,Markku Lepisto首先介紹了Amazon最新穎的各种云端服務,我們可以從What is Amazon Web Services?這段影片一窺究竟。
接著,MediaTek(聯發科)KKBoxTrend Micro(趨勢科技)也各自分享了它們運用AWS來處理企業需求的各种cases(案例)。其中,Trend Micro為了解決全球8座已採用Hadoop來處理big data(大數据)的data centers(數據中心)而需汰舊更新servers(伺服器)的困扰,毅然導入AWS的成功經驗是最誏筆者為之shock的!

因為筆者的教學與研究興趣著重於IoT,所以我們选擇参加了下午場的「行動化與物聯網」的section。
Markku Lepisto使用AWS提供的服務,在Intel的Edison開發板上展示了「云(端遙)控」的magic!
此外,Olivier Klein也当場demo AWS的Lambda services
可以很立即地deploy出适合IoT的cloud infrastructure
最後,Qblinks也展示了他們利用AWS建構IFTTT(If This Then That)並實作出Qmote產品的經彩範例!

P.S.今日的訍程在此

2015年11月10日 星期二

[App Inventor 2_LinkIt One] 使用App Inventor 2透过藍芽控制LinkIt ONE on-board的LED on/off(pin 13)


  • 我們試出來devices和LO較易配对的方法(藍芽配对的heuristics):
    1. 在device上刪除舊的藍芽配对(BTserverTest)
    2. Reset LO
    3. 開啟Arduino IDE的serial monitor等待device配对
    4. 以device搜尋LO

2015年10月12日 星期一

[App Inventor 2_Fusion Tables] 在App Inventor 2中存取Google的fusion tables資料庫


  • 操作流程:
1.設定Google fusion tables資料庫:FusionTables
    1. 完成設定好後FusionTables就会自动存到你的Google云端硬碟上供你自由存取資料
2.設定Google API:FusionTables
  1.   
3.使用AI 2存取fusion tables:fusion_Tables.aia
    1. 原使程式只要修改TABLE_URL、TABLE_ID與API_KEY這三塊積木:
  • fusion_Tables app執行畫面:



  • 参考資料(references):

2015年9月28日 星期一

[LinkIt One] LinkIt ONE一直被誤判為「Alcatel Single RNDIS Interface」

下載「第一個LinkIt One 程式,好吧,還是 Blink」上提及的「LinkIt-ONE-IDE」(試过了「Get the Hardware and Software」上的Arduino IDE 1.5.6-r2 BETA or 1.5.7 BETA都沒成功,TMD!):

  1. Arduino 1.5.8 把「LinkIt-ONE-IDE-master」copy到c:\xxx\下,xxx:destination folder
  2. LinkIt ONE SDK 1.0.42 安裝「LinkIt-ONE-IDE-master」內的 「mediatek_linkit_sdk_(for_arduino)-1.0.42.exe」
  3. 關閉Windows Update 開始->install driver->
之後U/L程式到LinkIt ONE時Windows就不会再雞婆地把它誤判成Alcatel的device了!(感謝StevenS

2015年9月20日 星期日

[Apps] Dance Yourself(iOS)

你也來跳一段騎馬舞吧!
App有時候還蠻有趣的:

2015年9月17日 星期四

Rhythmushi(iOS)

創作一首屬於你的歌吧!
[iPhone App] 做音樂的可愛程式:Rhythmushi:

[Apps] iCallMe(Android)

設定一重要事件的來電提醒
iCallMe --「來電提醒、一鍵脫逃」:

[Apps] Lollypop

製作一張3D擴增實境的卡片送給好友或家人吧!
[Mobile App] What's Lollypop?:
Lollypop – 製作3D擴增實境訊息、卡片

[Apps] Clone Camera

你也來訂製「分身」吧!
Clone Camera - multiplicity photography on iOS & Android.:

[Apps] Frontback

前後鏡頭同時拍,風景及掌鏡人全都錄喔!

Frontback for Android:

[Apps] 手相大師(Android)

iOS用「手相」搜

看看自己的手相唄!

手相大師:https://play.google.com/store/apps/details?id=teaonly.palmreader&hl=zh-TW

[Apps] KamiColle(iOS,女生用);Otokono KamiColle(iOS,男生用)

替自己設計一下新髮型吧!
iPhone app changes your hairstyle - KamiColle by Lucidol:

[Apps] Decide Now!(iOS);拋硬幣(Android)

「Decide Now!」現在就決定吧!:http://blog.yam.com/longson1001/article/59337027

https://play.google.com/store/apps/details?id=com.km.effects.coinflip&hl=zh_TW

中午吃什麼?搏杯吧!

[Apps] My Incredible Body

(Android免錢)

了解不可思訍的人体組成

[Apps] Google圖像搜尋(Android);picTrove Pro(iOS)

拍一張品商標、書籍、DVD、藝術品或條碼並請Google大神開示唄!

Apps - Google Goggles:

[Apps] Camera SX Pro(iOS)

誏你的照片說出它心中的OS吧!

讓照片說出心裡話語 Camera SX for iPad:http://www.iloveapps.hk/2013/05/08/camera-sx-for-ipad/

[Apps] 獎金答人

來A錢吧!

《獎金答人》什麼!!!上廁所也能賺錢!!!:http://www.cool3c.com/article/79516

[Apps] UTme

親手設計自己的潮T吧!

想擁有自己親手設計的 T-Shirt? 用這個 Uniqlo 新 App UTme!玩玩吧:http://www.cool3c.com/article/80858
作品:http://utme.uniqlo.com/

[Apps] Facebook 將在狀態欄中推出類似Shazam 的音樂和電視節目識別功能

https://tw.tech.yahoo.com/news/facebook-%E5%B0%87%E5%9C%A8%E7%8B%80%E6%85%8B%E6%AC%84%E4%B8%AD%E6%8E%A8%E5%87%BA%E9%A1%9E%E4%BC%BCshazam-%E7%9A%84%E9%9F%B3%E6%A8%82%E5%92%8C%E9%9B%BB%E8%A6%96%E7%AF%80%E7%9B%AE%E8%AD%98%E5%88%A5%E5%8A%9F%E8%83%BD-023500196.html

[Apps] Snippit(iOS)

訂做你的音樂照片吧!

Snippit™ – 好聽的照片分享社群:http://media.appshooting.com.tw/2014/02/snippit/
SNIPPIT PROMO v4 2:
--------------------------------------------------------------------------------------------------------------------------
相似app:SpeakingPhoto(限免):https://tw.tech.yahoo.com/news/%E3%80%90-dr-.-%E6%84%9B%E7%98%8B%E9%99%90%E6%99%82%E5%85%8D%E8%B2%BB%E8%BB%9F%E9%AB%94%E5%A0%B1%E5%A0%B1-%E3%80%91-131300920.html

[Apps] Superburst(iOS)

Superburst(iOS)

拍幾張精彩動作照片吧!

《Superburst》超高速連拍,您也可以拍出精彩動作影像:http://steachs.com/archives/3643#more-3643

[Apps] 城市也要智能化!顯示實時鐵路資訊的智能走道顯示系統!

http://www.newmobilelife.com/2014/05/19/smartwalk-projects-real-time-subway-info-sidewalk/

[Apps] 智能裝置也可作為家庭醫生!小小裝置可診斷常見疾病!

http://www.newmobilelife.com/2014/05/17/cue-home-medical-diagnostics/

[Apps] 【祖傳秘方】iPhone 耳機繞 8 字不打結收線法!

http://www.newmobilelife.com/2014/05/16/iphone-earphone-tide-up/
https://www.youtube.com/watch?v=uK0jZ5xnAEs

[Creativity] 一條充電線讓人們反思!看看這捐血機構的創意海報吧!

http://www.newmobilelife.com/2014/05/24/blood-charger-ads/

[Apps] (Sound Meter)測試一下你現在所處環境的吵雜程度


[Apps] 精選七大智慧型手機遙控科技玩具,你心動了嗎?

http://www.app01.com.tw/paper/2ae7d5d7-0715-49d6-bf78-c1c3e9342c37

[Apps] Coca-Cola Friendly Twist

[Funny] 師父,讓我睡嘛!


愛玩臉書的人 看完這支影片都掉淚了

https://tw.screen.yahoo.com/%E6%AF%8F%E5%A4%A9%E7%8E%A9%E8%87%89%E6%9B%B8%E7%9A%84%E4%BA%BA-%E5%AE%9A%E8%A6%81%E7%9C%8B%E9%80%99%E6%94%AF%E5%BD%B1%E7%89%87-105055845.html

雷射投影虛擬鍵盤

[限時促銷]雷射投影虛擬鍵盤終於來了Orz,喬了好久總算搶在上市之前再拉一波預購:http://www.cool3c.com/article/74326

2015年7月10日 星期五

AI2的限制


  1. 程式積木一長就不好找
  2. 無法redo/undo