Pages

Subscribe:

Ads 468x60px

Labels

2013年6月3日 星期一

Ken Yang 筆記: Arduino 基本教學

Ken Yang 筆記: Arduino 基本教學: Arduino 是一塊Open Source電路板, 開發者可以利用這塊板子去做到一些電子器材的控制, 例如:開燈、關燈,甚至可以在Arduino上裝上sensor, 然後根據sensor的資料來做處理!例如接上了光敏電阻這個sensor, 我們就可以判斷目前光的亮度,就...

用 Android 手機透過藍牙與 Arduino 溝通(二)

在上一篇已經準備好了 Android App 程式(MultiColor Lamp)﹐並且把 Bluetooth 模組的 Baud rate 也設置好了﹐接下來我們要把各項組合起來﹐這裏我使用的 bluetooth 模組是用 XBee 型式的。
在開始之前要先把 sketch 程式寫到 arduino ATmega 328 中(sketch 在所下載的 MultiColorLamp.zip 之中)﹐在寫入之前最好將arduino 板子上的東西都先移除﹐才不會出現干擾。
MultiColorLamp_pde
接下來就要開始將必要的線路全部接上
arduino_Moto_led

由上圖﹐在麵包板上插上三個 Led 燈﹐紅﹑綠﹑黃﹐並分別將三個 Led的正極接腳接到Xbee 傳感器擴展板V5的 9,10,11 腳位﹐負極則接到 GND 的位置﹐這樣就一切就緒了。
現在一切都俱備﹐只要將 Arduino 接上USB就可以了﹐在影片上可以看到當 arduino 接上USB 之後﹐過一會三個燈會全部亮起來﹐這是因為在 sketch 中 setup() 時把腳位都設為 HIGH﹐所以一開始三顆燈都亮了。而在手機的藍牙連線上後可能會全部熄滅(因為在 Android App 程式的 OnStart 中會先讀取在上一次App程式離開前所儲存的數值)﹐接著就可以用手機來控制燈號。


根據上述的程式﹐只要把 sketch 程式稍微修改﹐再搭配電機﹑馬達就可以遙控小車了。這裏把原本做避障的小車稍微修改原本的 sketch 程式就能遙控了﹐不過這是拿原本的 sketch 程式修改搭配原本的 App程式﹐操控上不是很好﹐不過現在只是先讓藍牙溝通沒問題﹐下次再找時間好好的根據所要的性能來撰寫程式了。

用 Android 手機透過藍牙與 Arduino 溝通(一)

之前曾在YouTuBe上看過影片﹐有人用android手機搖控小車﹐因此也一直在找這方面的資料﹐直到有次看到[Arduino]_用Android手機經Bluetooth遙控Arduino小車 這篇文章﹐才知道原來早就有sample可用。透過MULTI COLOR LAMP USING AMARINO, ANDROID AND ARDUINO這個範例﹐可以輕鬆的做到用Android和Arduino透過bluetooth來溝通。雖是如此我還是碰到了一些障礙﹐幸好網路上總是有高手可以幫忙。
在 MULTI COLOR LAMP USING AMARINO, ANDROID AND ARDUINO 這篇文章已經很詳細的說明了整個步驟與所需要的軟體﹐或者也可以參考 Cooper 的文章中文的比較容易了解。
上述的文章都已有做法了﹐不再累述﹐在這僅整理我所遇到的問題。
1. Android App程式 Multicolor Lamp
Multicolor Lamp App 將透過藍牙控制連接在Arduino上的三個燈號改變亮度。 Multicolor Lamp 不需要改變任何程式碼﹐唯一要改的是bluetooth 的 MAC address﹐上述的網站都有詳細的描述。編譯好程式後就可以將apk程式放到手機上執行即可。不過﹐我在這裏卡關了一陣子。這個App程式在我的桌機上以模擬器執行每次都異常終止﹐我想可能是桌機沒有藍芽設備的關係﹐每次都是在onCreate中的Amarino.connect(this, DEVICE_ADDRESS); 死掉﹐而把App放到手機上﹐還是一樣一執行就出現異常終止。
後來在Eclipse上執行直接選擇以實機做連接不透過模擬器﹐竟然成功的執行一次﹐但之後就又不行。之後我改使用一台NB﹐剛開始的情況和桌機相同﹐但以NB和手機做實機連線執行﹐倒是每次都可以。然後在不知什麼原因之下﹐在NB上用模擬器執行Multicolor Lamp也可以了。網路上沒找到有人跟我相同的狀況。
桌機和NB主要的不同﹐桌機OS是Win7 x64 ﹐NB OS是Win7 x86﹐另一個是Eclipse同樣是x64與x86的不同﹐猜測在程式中引用的AmarinoLibrary_v0_55.jar 可能在64位元之下比較不相同吧﹐這是純猜測還沒深究。
2.Baud rate的設定
我所使用的Bluetooth模組是XBee型式﹐網路上的範例都不是使用這種﹐這點又讓我卡了很久。但﹐不管用那一種﹐正確的設定baud rate都是必須的。因為原本的Bluetooth Bee v2一直搞不定﹐看到網路上另一個模組不到三百元﹐所以又買了另一張
bluetooth_rs232
不論使用那一種﹐都必須先設定好 baud rate﹐以此例而言﹐設定為57600是比較適合的﹐設定的方式可以參考 Motoduino 上修改藍芽模組Baud Rate ﹐其中腳位的接法
Bluetooth Arduino
TX-RX
RX-TX
GND-GND
VCC-3.3V
使用上述文章中的方式就可以修改baud rate 了。
而我原本使用的Bluetooth Bee V2 一張可要近千元﹐怎麼可以棄而不用呢?如果要修改根據手冊是要搭配一張XBee USB Adapter ﹐不過這又要花錢﹐ 幸好sinocgt 的文章幫了大忙 DFRduino (Arduino): changes the baud rate of Bluetooth Bee v2 on the IO Expansion Shield V5 省了一筆錢又有DIY的精神。
bluetooth_bee_set
1.拔除ATMEGA328 IC。
2.擴展板V5 上的 RS232/RS385 Jump 拔起﹐並用杜邦線跳線﹐如圖上紅色框處。
3.將Bluetooth Bee V2 的switch 撥到 AT mode 並插到擴展板上﹐如圖上綠色框處。
4.將USB 接到Arduino上。
5.在電腦上執行SSCOM3.2或AccessPort之類的軟體。(SSCOM3.2蠻多人用的﹐但在我的電腦執行後所有的文字都是亂碼﹐所以改用AccessPort)
6.在AccessPort 上加AT指令。以此張Bluetooth bee v2 所要下的指令為 AT+UART=57600,0,0
   執行了AccessPort﹐第一件事先設定使用的COM Port是那一個。
   先下AT﹐正確的話會回應 OK
   然後再下AT+UART=57600,0,0
   送出後﹐正確的話會回應 OK
    這時可以下 AT+UART﹐如果回應是 +UART:57600,0,0 那麼就代表已經修改好了。
    AccessPort

到此﹐Bluetooth 的baud rate 都已修改好﹐接下來就是將sketch的程式和 Led 燈接上就差不多了﹐下一篇再說了。

Ken Yang 筆記: Android Bluetooth API

Ken Yang 筆記: Android Bluetooth API: 這篇主要教大家怎麼用Bluetooth API去 搜尋裝置 連結 裝置 傳送指令至裝置上 首先要先宣告下列三個物件與常數, private static BluetoothAdapter mBluetoothAdapter = null; // 用來搜尋、管理藍...

Android Bluetooth API 使用心得筆記

1.Bluetooth基本概念
可以參考BlueCove這個實作JSR82的Project,裡面的這張圖對Bluetooth解說很清楚,可供參考。

Bluetooth Stack的部份在不同系統、程式語言上都是相同的,會有差異的只有頂層的Abstract API。

若想對Bluetooth整體軟硬体有仔細的了解可以參考「Bluetooth Application Programming with the Java APIs Essentials Edition」這本書。

2.Android Bluetooth開發基本需求
Android SDK 2.0以上(含2.0)版本。
支援Android 2.0的手機一隻(Android Emulater無法模擬Bluetooth,所以一定要有實體手機)。

3.實作參考文件
http://developer.android.com/guide/topics/wireless/bluetooth.html
http://www.anddev.org/serial_over_bluetooth_simple_test_client-t11106.html

一般來說,我們只會實作Bluetooth Client的程式去跟其它的Bluetooth硬體溝通取資料。連線方式大多是利用Serial Port Service方式去跟遠端的裝置溝通,所以相對應的UUID不能設錯,一定要設成下述範例這組UUID,不然會發生找不到Service的問題(附帶一提,這是假設一般遠端裝置有提供Serial Port Service,所以你才可以用這組UUID來進行通訊,如果遠端裝置比較特別就要去查硬體規格去看它提供的Service是哪些,找出對應的UUID)。

1
private static final UUID SERIAL_PORT_SERVICE_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");


4.Android Bluetooth API目前的限制
目前只支援RFCOMM的方式進行通訊

5.實作參考範例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
// 取自http://www.anddev.org/serial_over_bluetooth_simple_test_client-t11106.html裡的範例
package  com.example.thinbtclient;
 
import java.io.IOException;
import java.io.OutputStream;
import java.util.UUID;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
 
public class ThinBTClient extends Activity {
     
     private static final String TAG = "THINBTCLIENT";
     private static final boolean D = true;
     private BluetoothAdapter mBluetoothAdapter = null;
     private BluetoothSocket btSocket = null;
     private OutputStream outStream = null;
     // Well known SPP UUID (will *probably* map to
     // RFCOMM channel 1 (default) if not in use);
     // see comments in onResume().
     private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
 
     // ==> hardcode your server's MAC address here <==
     private static String address = "XX:XX:XX:XX:XX:XX";
 
     /** Called when the activity is first created. */
     @Override
     public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.main);
 
          if (D)
               Log.e(TAG, "+++ ON CREATE +++");
 
          mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
          if (mBluetoothAdapter == null) {
               Toast.makeText(this,
                    "Bluetooth is not available.",
                    Toast.LENGTH_LONG).show();
               finish();
               return;
          }
 
          if (!mBluetoothAdapter.isEnabled()) {
               Toast.makeText(this,
                    "Please enable your BT and re-run this program.",
                    Toast.LENGTH_LONG).show();
               finish();
               return;
          }
 
          if (D)
               Log.e(TAG, "+++ DONE IN ON CREATE, GOT LOCAL BT ADAPTER +++");
     }
 
     @Override
     public void onStart() {
          super.onStart();
          if (D)
               Log.e(TAG, "++ ON START ++");
     }
 
     @Override
     public void onResume() {
          super.onResume();
 
          if (D) {
               Log.e(TAG, "+ ON RESUME +");
               Log.e(TAG, "+ ABOUT TO ATTEMPT CLIENT CONNECT +");
          }
 
          // When this returns, it will 'know' about the server,
          // via it's MAC address.
          BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
 
          // We need two things before we can successfully connect
          // (authentication issues aside): a MAC address, which we
          // already have, and an RFCOMM channel.
          // Because RFCOMM channels (aka ports) are limited in
          // number, Android doesn't allow you to use them directly;
          // instead you request a RFCOMM mapping based on a service
          // ID. In our case, we will use the well-known SPP Service
          // ID. This ID is in UUID (GUID to you Microsofties)
          // format. Given the UUID, Android will handle the
          // mapping for you. Generally, this will return RFCOMM 1,
          // but not always; it depends what other BlueTooth services
          // are in use on your Android device.
          try {
               btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
          } catch (IOException e) {
               Log.e(TAG, "ON RESUME: Socket creation failed.", e);
          }
 
          // Discovery may be going on, e.g., if you're running a
          // 'scan for devices' search from your handset's Bluetooth
          // settings, so we call cancelDiscovery(). It doesn't hurt
          // to call it, but it might hurt not to... discovery is a
          // heavyweight process; you don't want it in progress when
          // a connection attempt is made.
          mBluetoothAdapter.cancelDiscovery();
 
          // Blocking connect, for a simple client nothing else can
          // happen until a successful connection is made, so we
          // don't care if it blocks.
          try {
               btSocket.connect();
               Log.e(TAG, "ON RESUME: BT connection established, data transfer link open.");
          } catch (IOException e) {
               try {
                    btSocket.close();
               } catch (IOException e2) {
                    Log.e(TAG,"ON RESUME: Unable to close socket during connection failure", e2);
               }
          }
 
          // Create a data stream so we can talk to server.
          if (D)
               Log.e(TAG, "+ ABOUT TO SAY SOMETHING TO SERVER +");
 
          try {
               outStream = btSocket.getOutputStream();
          } catch (IOException e) {
               Log.e(TAG, "ON RESUME: Output stream creation failed.", e);
          }
 
          String message = "Hello message from client to server.";
          byte[] msgBuffer = message.getBytes();
          try {
               outStream.write(msgBuffer);
          } catch (IOException e) {
               Log.e(TAG, "ON RESUME: Exception during write.", e);
          }
     }
 
     @Override
     public void onPause() {
          super.onPause();
 
          if (D)
               Log.e(TAG, "- ON PAUSE -");
 
          if (outStream != null) {
               try {
                    outStream.flush();
               } catch (IOException e) {
                    Log.e(TAG, "ON PAUSE: Couldn't flush output stream.", e);
               }
          }
 
          try  {
               btSocket.close();
          } catch (IOException e2) {
               Log.e(TAG, "ON PAUSE: Unable to close socket.", e2);
          }
     }
 
     @Override
     public void onStop() {
          super.onStop();
          if (D)
               Log.e(TAG, "-- ON STOP --");
     }
 
     @Override
     public void onDestroy() {
          super.onDestroy();
          if (D)
               Log.e(TAG, "--- ON DESTROY ---");
     }
}
 
AndroidManifest.xml裡的Permission設定加下述二行
"android.permission.BLUETOOTH_ADMIN"
/> "android.permission.BLUETOOTH" />

Android SDK 2.1裡的Bluetooh Sample (在 x:/android sdk安裝目錄/platforms/android-2.1/samples/BluetoothChat 裡面,或是到 http://developer.android.com/resources/samples/BluetoothChat/index.html 看範例,二者是一樣的東西)

http://code.google.com/p/apps-for-android/ 裡面有個 BTClickLinkCompete Sample,可經由SVN去下載回來看 


資料來源