arduino 習作工坊 - lesson 4 通訊之夜
TRANSCRIPT
Arduino PlusMakerBar Taipei Workshop
Part 1:藍牙
JY-MCU•
•••••
預設
Baud rate 9600Name HC-0XPairing code 1234
Pin ID Description1 EN Enable / Disable module2 VCC 3.6V ~ 6V3 GND Comman Ground4 TXD UART TXD Output5 RXD UART RXD Input6 STATE
USB to TTL
AT Command
• 修改Baud rate, name, password…. 網址→Arduino as an USB to TTL adapter網址→AT指令集
藍牙接Arduino
Arduino 藍牙模組 備註
5V VCC 注意電源不可接錯
GND GND 注意電源不可接錯
RXD (pin 0) RXD
TXD (pin 1) TXD
測試藍牙連接
打開 Serial Monitor 把換行模式改成 "No line ending" 接著輸入 AT 指令(指令全部大寫) 然後按下 Send 按鈕或 Enter 鍵 這時藍牙模組應該會回應 OK
註:此時需接一條線在Arduino的GND與RESET,讓 Arduino停留在TTL mode
修改藍牙名稱
• 修改藍牙設備名稱(預設為 linvor) 指令:AT+NAME<p> 回應:OKsetname 其中: <p> 為 Parameter,即設備名稱,有效字元 20 個 範例:將藍牙設備名稱改為 CAVEDU 指令:AT+NAMECAVEDU 回應:OKsetname • 修改藍牙配對密碼(預設為 1234) 指令:AT+PIN<p> 回應:OKsetPIN 其中: <p> 為 Parameter,即配對密碼,有效字元 4 個 範例:將配對密碼改為 5678 指令:AT+PIN5678 回應:OKsetPIN
註:記得將接在Arduino的GND與RESET中間的線拔掉,解除TTL Mode
Part 1:藍牙
EX1:LED
App Inventor2
App Inventor2
App Inventor2http://ai2.appinventor.mit.edu/
Installing and Running the Emulator in AI2
• 下載模擬器http://appinventor.mit.edu/explore/ai2/setup-emulator.html
• 打開 Aistarter
下載MIT AI2 Companion App
讓手機可安裝App Inventor程式
• 需要在手機的設定頁面中完成「未知的來源」、「USB除錯中」、「允許模擬位置」等設定
• 連接Wifi
嘗試連接模擬器及手機
• Connect => Emulator • Connect => Reset • Connect => AI Companion
釐清副檔名
• .apk • 手機 app
• .aia • app inventor 程式原始檔
• .fzz • fritzing原始檔
20
手機程式
手機程式
手機程式
ASCII CodeASCII(American Standard Code for Information Interchange,美國訊息交換標準代碼)是基於拉丁字母的一套電腦編碼系統。它主要用於顯示現代英語,而其擴展版本EASCII則可以部分支援其他西歐語言,並等同於國際標準ISO/IEC 646。由於全球資訊網使得ASCII廣為通用,直到2007年12月,逐漸被Unicode取代。
常用到的ASCII Code
圖形 十進制 圖形 十進制 圖形 十進制
0 48 5 53 a 97
1 49 6 54 b 98
2 50 7 55 c 99
3 51 8 56 A 65
4 52 9 57 B 66
電路圖
腳位對應表
LED+ 13
LED- GND
BT-RXD 11
BT-TXD 10
SoftwareSerial I2CBT(a,b) a=arduino的接收腳(RxD) b=arduino的傳送腳(TxD) 藍牙端TXD接arduino RxD(pin 10) 藍牙端RXD接arduino TxD(pin 11)
#include <SoftwareSerial.h> #include <Wire.h>
int LED = 13; SoftwareSerial I2CBT(10,11);
void setup() { Serial.begin(9600); I2CBT.begin(9600); pinMode(LED, OUTPUT); }
void loop() {
byte cmmd[20]; int insize; while(1){ /* read message from bluetooth */ if ((insize=(I2CBT.available()))>0){ Serial.print("input size = "); Serial.println(insize); for (int i=0; i<insize; i++){ Serial.print(cmmd[i]=char(I2CBT.read())); Serial.print("\n"); } }
switch (cmmd[0]) { case 97: //"a" digitalWrite(LED,HIGH); break; case 98://"b" digitalWrite(LED,LOW); break; } //Switch } //while
}
Part 1:藍牙
EX2:Slider
手機程式
手機程式
手機程式
手機程式
#include <SoftwareSerial.h>
#include <Wire.h>
SoftwareSerial I2CBT(10,11);
void setup() {
Serial.begin(9600);
I2CBT.begin(9600);
pinMode(9,OUTPUT);
}
///////////////////main////////////////
void loop() {
byte cmmd[20]; int insize; int a=0; while(1){ if ((insize=(I2CBT.available()))>0){ Serial.print("input size = "); Serial.println(insize); for (int i=0; i<insize; i++){ //cmmd[i]=char(I2CBT.read()); Serial.print(cmmd[i]=char(I2CBT.read())); Serial.print(" "); } Serial.println(" "); }
if(insize==4){
a = (cmmd[0]-48)*10;
a=a+(cmmd[1]-48);
}
if(insize==3){
a=(cmmd[0]-48);
}
Serial.println(a);
analogWrite(9,map(a,0,80,0,255));
} //while
}
Part 1:藍牙
EX3:Send message to phone
到目前為止,我們使用的傳輸方式仍然符合無線傳輸的限定範圍,也就是說資料都在0~255之間。
但如果今天有一筆資料是超過這個範圍的要如何進 行傳輸?
封包的傳送與接收
封包(Packet): 電腦傳輸資料的基本單位,通常一 個標頭加上一段資料,就可稱為一個封包。
封包的傳送與接收如果我們有一筆1013的資料,要如何做成封包?
編碼
高位元 資料
低位元 資料
建立封包
封包的傳送與接收
收到此陣列資料Data[2]後,要如何將其解碼並求得值為多少?
編碼
確認起始封包位
計算高低位元
求得其值
封包的傳送與接收
在電腦端,一個位元組的資料是0~255,但是當資料傳送到Arduino時,它卻會將128~255的資料誤判為-128~-1。
1位元組: 0~255
解碼
PC: 0~127→Arduino: 0~127 PC: 128~255→Arduino: -128~-1
封包的傳送與接收
封包解碼與接收
電路圖元件 arduino
VR-訊號線 A0
BT-TXD 10
BT-RXD 11
BT-GNDGND
VR-GND
BT-Vcc5V
VR-5V
手機程式
手機程式
手機程式
#include <SoftwareSerial.h>
#include <Wire.h>
SoftwareSerial I2CBT(10,11);
byte serialA;
void setup(){
//define pin modes for tx,rx pin
pinMode(10,INPUT);
pinMode(11,OUTPUT);
Serial.begin(9600);
I2CBT.begin(9600);
}
///////////////////main///////////////////
void loop (){ byte Data[3]; byte cmmd[20]; int insize; int i=analogRead(A0); serialA=I2CBT.read(); Data[0]='a'; Data[1]=i/256; Data[2]=i%256; Serial.println(i); if (serialA == 49){ for(int j=0;j<3;j++) I2CBT.write(Data[ j]); serialA=0; } delay(100); }
封包
48
app inventor 經由clock
用藍芽傳送a
arduino收到a之後 用藍芽傳送data
app inventor收到Data[0]=a 接收其他data[1] data[2]
再解封包
程式邏輯
CAVEDU:雙A計劃
• Appinventor+Arduino – Part 0 – Part 1 – Part 2 – Part 3
Part 2:紅外線
51
http://www.mobile01.com/topicdetail.php?f=168&t=4135366&p=1#52856899
紅外線
紅外線是目前最常見的一種無線通訊,普遍使用在家電以及玩具產品,如電視、音響、錄放影機、冷氣機、DVD、MP3 Player、遙控車等。紅外線遙控之所以被大量採使用,主要是因為紅外線裝置體積小、成本低、耗電少及硬體設計容易。
Add library
• <IRremote.h> – IRrecv irrecv(irReceiverPin); // 定義 IRrecv 物件來接收紅外線訊號 – irrecv.enableIRIn(); // 啟動紅外線解碼 – showIRProtocol // 顯示紅外線協定種類
Part 2:紅外線
EX1:TurnOnLED
TURNON_LED/* * IRRemote 紅外線遙控教學 * 範例 1.2: 顯示紅外線協定種類; 如 NEC, Sony SIRC, Philips RC5, Philips RC6 等協定 */ #include <IRremote.h> // 引用 IRRemote 函式庫
const int irReceiverPin = 2; // 紅外線接收器 OUTPUT 訊號接在 pin 2 int i=0; IRrecv irrecv(irReceiverPin); // 定義 IRrecv 物件來接收紅外線訊號 decode_results results; // 解碼結果將放在 decode_results 結構的 result 變數裏 int LED=13; void setup() { Serial.begin(9600); // 開啟 Serial port, 通訊速率為 9600 bps irrecv.enableIRIn(); // 啟動紅外線解碼 pinMode(13,OUTPUT); }
5v
GND
arduino-2
// 顯示紅外線協定種類 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"); }
// 把紅外線編碼印到 Serial port Serial.print(", irCode: "); Serial.print(results->value, HEX); // 紅外線編碼 Serial.print(", bits: "); Serial.println(results->bits); // 紅外線編碼位元數 }
void loop() { if (irrecv.decode(&results)) { if (results.value != -1) { showIRProtocol(&results); if(i==0) { digitalWrite(LED, HIGH); i=i+1; } else if(i==1) { digitalWrite(LED, LOW); i=i-1; } } irrecv.resume(); // 搬到外面來 } }
Part 2:紅外線
EX2:Fade the LED
FADE_LED/* * IRRemote 紅外線遙控教學 * 範例 1.2: 顯示紅外線協定種類; 如 NEC, Sony SIRC, Philips RC5, Philips RC6 等協定 */ #include <IRremote.h> // 引用 IRRemote 函式庫
const int irReceiverPin = 2; // 紅外線接收器 OUTPUT 訊號接在 pin 2 int i=0; IRrecv irrecv(irReceiverPin); // 定義 IRrecv 物件來接收紅外線訊號 decode_results results; // 解碼結果將放在 decode_results 結構的 result 變數裏
void setup() { Serial.begin(9600); // 開啟 Serial port, 通訊速率為 9600 bps irrecv.enableIRIn(); // 啟動紅外線解碼 pinMode(13,OUTPUT); }
// 顯示紅外線協定種類 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"); }
// 把紅外線編碼印到 Serial port Serial.print(", irCode: "); Serial.print(results->value, HEX); // 紅外線編碼 Serial.print(", bits: "); Serial.println(results->bits); // 紅外線編碼位元數 } void loop() { if (irrecv.decode(&results)) { // 解碼成功,收到一組紅外線訊號 showIRProtocol(&results); // 顯示紅外線協定種類 irrecv.resume(); // 繼續收下一組紅外線訊號
void loop() { if (irrecv.decode(&results)) { if (results.value != -1) { showIRProtocol(&results); if(i==0) { analogWrite(9, 0); i=i+1; } else if(i==1) { analogWrite(9, 64); i=i+1; } else if(i==2) { analogWrite(9, 255); i=i-2; } Serial.println(i); } irrecv.resume(); // } }
參考資料
• CooperMaa 紅外線遙控教學