2015年7月23日

Android App - Bluetooth 初探 ( 2 )

BluetoothDevice
接下來要熟悉的是BluetoothDevice這個類別。我們已經知道BluetoothAdapter代表的是Android手機裡的藍芽裝置,那麼就可以把BluetoothDevice想像成其它的藍芽裝置,比如說;藍芽耳機、藍芽喇叭、小米手環...等各式各樣的裝置。

現在,我們的App已經可以利用BluetoothAdapter來開關Android手機裡的藍芽設備,接著我們可以再利用BluetoothAdapter這個類別來找出已經和我們的Android手機配對完成的藍芽裝置,並顯示它們的名稱以及位址。延續之前的程式碼,我們在MainActivity.java中加入
public void findDevice(View view) {
    ArrayAdapter<String> mArrayAdapter = new ArrayAdapter(this, 
                                  android.R.layout.simple_list_item_1);
    Set<BluetoothDevice> pairedDevices = mBTadapter.getBondedDevices();
    if ( pairedDevices.size() > 0 ) {
        for (BluetoothDevice device : pairedDevices) {
            mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
            ListView listview = (ListView)findViewById(R.id.listView);
            listview.setAdapter(mArrayAdapter);
        }
    }
}
利用BluetoothAdapter提供的getBondedDevices()方法可以取得已經和我們的Android手機配對完成的裝置。這個方法會回傳BluetoothDevice物件,而且存放於Set這種型式的container裡。我們可以利用BluetoothDevice類別裡的getName()與getAddress()分別取得藍芽裝置的名稱以及位址。最後,使用ListView把藍芽裝置的名稱與位址一筆一筆地顯示出來。
activity_main.xml 加入

<Button 
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:onClick="findDevice" 
android:text="@string/find_device" 
android:layout_alignParentTop="true" 
android:layout_alignParentRight="true" 
android:layout_alignParentEnd="true" /> 

<ListView 
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:id="@+id/listView" 
android:layout_below="@+id/button" 
android:layout_alignParentLeft="true" 
android:layout_alignParentStart="true" 
android:layout_marginTop="51dp" />

strings.xml 加入

<string name="find_device">搜尋裝置</string>

新增一個按鈕「搜尋裝置」




按下搜尋裝置按鈕之後,會顯示已經配對完成的裝置名稱,以我的Android手機來說,總共有兩個配對完成的藍芽裝置。



2015年7月21日

Arduino - 利用UART上傳程式到麵包板上的Arduino ATMega328P-PU

現在,新購入的ATMega328已經有Bootloader在裡面,我們可以透過UART來上傳程式到ATMega328晶片中。我使用的方法有兩個,說明如下;

一. 利用Arduino UNO實驗板上傳(upload)程式
首先,先把Arduino UNO實驗板上的ATMega328P-PU晶片拔出。
ATMega328P-PU的線路接法如下電路圖所示


A_Tx:        接到UNO實驗板的Tx
A_Rx:        接到UNO實驗板的Rx
A_RESET: 接到UNO實驗板的RESET











麵包板上的接線圖片如下





注意: 
A_Tx 與 麵包板上的ATMega328 Tx連接
A_Rx與 麵包板上的ATMega328 Rx連接
不必對調!










在線路上加了一顆LED與220歐姆的電阻是用來測試Arduino的範例程式(Blink sketch),以驗證我們上傳程式是否成功(如果上傳成功則LED會閃爍)。


二. 利用USB轉UART轉接板上傳(upload)程式



原理與方法一一樣,有兩個不同的地方要注意:
1. 要加上一個RESET開關,接到ATMega328的第一支腳位。
2. UART的Tx要接到ATMega328的Rx,UART的Rx要接到ATMega328的Tx。











因為增加了一個USB轉UART的裝置,因此COM port會增加一個,我增加的COM port名稱是COM9,在Arduino IDE中[工具]->[序列埠]要選擇COM9,如此才能正確地上傳。





















注意:
當選擇上傳,程式碼編譯完成時,要按一下RESET按鈕,這樣bootloader才能與Arduino IDE連接,開始上傳程式。

2015年7月20日

Arduino - 以Arduino UNO開發板當作ISP燒錄器,燒錄Bootloader到新買的ATMega328P-PU晶片中

新買了一顆型號為ATMega328P-PU的MCU,裡面空空如也!

市面上在賣的MCU,有的賣家會幫顧客預先燒錄Bootloader,以利顧客後續開發作業,也有賣家只賣「全裸的」,如果沒有Arduino的實驗板、AVR的ISP programmer或是萬用燒錄器,就不要買全裸的,否則,我真不知道你該怎麼把寫好的firmware燒錄到MCU裡。

因為我有Arduino UNO的實驗板,因此除了以實驗板做開發之外,也可以把它用來燒錄我新購的ATMega328P-PU。我使用的方法如下;
工作電路圖 :





所需電子零件:
ATMega328P-PU
石英震盪器 16MHz 一個
陶瓷電容 22pF 兩個
電阻10k歐姆 一個











麵包板接線圖:



1. 打開Arduino IDE(我目前使用1.6.5版)






















2.點選「檔案」->「範例」裡的 「ArduinoISP」




3. Arduino IDE會開啟另外一個畫面,且載入ArduinoISP,
在程式碼中可以看到腳位的定義。





















4. 將ArduinoISP上傳至Arduino UNO實驗版,完成後會看到「上傳完畢」的訊息。





















5. 點選「工具」選項,確認要被燒錄bootloader的型號(我要燒錄ATMega328P-PU,
因此我選擇Arduino UNO),之後再點選「燒錄Bootloader」選項,即開始燒錄
bootloader,約需幾秒鐘的時間就可完成。



6. 燒錄完成會在訊息框裡顯示「bootloader燒錄完畢」。






2015年7月19日

Android App - Bluetooth 初探 ( 1 )

在Bluetooth API中,有幾個基本類別必須熟悉

BluetoothAdapter
可以把它想像成,這個類別就等同於Android手機裡的藍芽裝置。這樣就很容易理解了!很直覺地,當我們想要操作Bluetooth裝置,就可以透過BluetoothAdapter這個類別來執行。
那麼,要使用它必須先物件化,可以透過getDefaultAdapter()這個方法來產生BluetoothAdapter類別的物件,例如;下列的程式碼宣告且產生一個BluetoothAdapter類別的物件,其名稱為mBTadapter;

BluetoothAdapter mBTadapter = BluetoothAdapter.getDefaultAdapter();

我們要先判斷mBTadapter是否物件化成功,即mBTadapter != null,如果mBTadapter == null,就表示我們的Android 手機沒有藍芽功能。

接著,我們可以嘗試使用幾個BluetoothAdapter提供的方法,例如; isEnabled(), disable()
isEnabled()用來判斷藍芽裝置目前是否已經準備好了可以開啟,如果回傳值是true,表示可以打開藍芽裝置。要開啟藍芽裝置可以透過startActivityForResult()這個方法來達成,程式片段如下;
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, REQUEST_BT_ENABLE);
其中,REQUEST_BT_ENABLE是自己定義的整數其值必須大於零。

disable(),則是用來關閉藍芽裝置。

整個程式的原始碼加入藍色字體的部分即可

public class MainActivity extneds ActionBarActivity {
    private static final int REQUEST_BT_ENABLE = 2;
    BluetoothAdapter mBTadapter = BluetoothAdapter.getDefaultAdapter();

    public void BTOn(View view) {
        if(!mBTadapter.isEnable()) {
            Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(intent, REQUEST_BT_ENABLE);
        } else {
            Toast.makeText(getApplicationContext(), "已經開啟", Toast.LENGTH_LONG).show();
        }
    }
    
    public void BTOff(View view) {
          if(mBTadapter.isEnable()) {
            mBTadapter.disable();
            Toast.makeText(getApplicationContext(), "關閉藍芽", Toast.LENGTH_LONG).show();
        } else {
            Toast.makeText(getApplicationContext(), "已經開啟", Toast.LENGTH_LONG).show();
        }
    }
}

activity_main.xml 加入
<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:onClick="BTOn"
    android:text="@string/button_on"
    android:id="@+id/button" />
<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:onClick="BTOff"
    android:text="@string/button_off"
    android:layout_alignTop="@+id/button"
    android:layout_centerHorizontal="true" />

strings.xml加入
<string name="button_on">開啟藍芽</string>
<string name="button_off">關閉藍芽</string>

最後,AndroidManifest.xml要加入
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

程式開始執行的畫面





















按下開啟藍芽之後,請求允許開啟藍芽的權限




















按下關閉藍芽之後,藍芽裝置即被關閉

2015年7月17日

把舊筆電當作embedded system平台來實驗(1)

既然,IA32的boot loader已經建構好了,接著當然可以寫一些簡單的程式來做探索,其實家中的舊筆電是很好的實驗平台。未來物聯網的世界會更大量的使用embedded system,因為半導體技術的發達,32位元的MCU會成為主流,隨著CPU的速度、記憶體容量的提升,每個物聯網裝置內部勢必都會有作業系統在運作,因此,對於embedded system作業系統的運作原理已經是基礎知識。
要了解這些基礎知識不需要花大錢買設備或器材,只要家裡的舊筆電就可以當作研究平台,其它的資源都可以靠Google來尋找,這是現代世界的學習方法,靠搜尋引擎來尋找需要的知識,靠大腦與手來驗證知識的正確性,進而成為經驗與技能。

回歸主題,上次寫好的bootloader,主要的工作就是在USB Flash Disk中尋找檔名為embedded.bin的檔案,然後將它載入到啟始位址為0000:0000的位置,然後讓CPU從位址為0000:0000的地方開始執行指令。從power on開始到載入embedded.bin的過程CPU都是以16位元的模式在運作,我們的目標是讓筆電成為32位元的embedded system,要用來理解32位元的作業系統,因此,接下來就是要把CPU切換到32位元的模式下運作。這個部分不難,只要做些簡單的設定即可,短短幾行組合語言指令就可以把CPU切換到32位元模式下運作。
程式碼下載
執行步驟 :
1. 組譯startup.asm
    程式碼原始檔組譯方式 -
    nasm startup.asm -o embedded.bin
2. 將embedded.bin 複製到USB Flash Disk 中
3. 將USB Flash Disk 插入舊筆電中,power on,即可在螢幕的左上角看到黑底紅字的X,
    這表示CPU已經以32位元模式在運作了。

* 舊筆電的BIOS記得要設定成USB Flash Disk 開機喔!


2015年7月8日

在Google Map中設立一個標記


標記(Marker)在Google地圖中用來標註一個位置。在Google Map API裡,屬於一種物件,其實標記也就是一種Icon。這種Icon用圖層重疊的方式疊放於底圖上而產生效果。
既然,Marker是一種物件,那麼在使用它的時候就需要初始化它,例如;

var markerSchool = new google.maps.Marker({
                    position:myLatlng,
                    map:map,
                    title:'榮富國小'
});

這個宣告是說,在地圖座標myLatlng上建立一個Marker,且這個Marker顯示出來的名稱是「榮富國小」。產生的結果如下:

範例原始碼

2015年7月5日

IA32 boot code



這裡,有一段IA32的boot code,用於FAT32的檔案系統格式。可以使用NASM assembler,組譯成binary code,寫入USB Flash Disk的開機磁區。
組譯的方式:
1. 打開cmd.exe
2. 執行 nasm -f bin -o bootload.bin bootload.asm
3. 最後會產生bootload.bin檔

寫入USB Flash Disk的方式:
1. 執行BootWriter.exe
2. 在Write to USB Flash Disk功能區中,點選Write按鈕
3. 選擇bootload.bin所在的位置後,即會將bootload.bin寫入開機磁區

這個boot code主要的工作有兩個,一是在FAT32檔案系統中找出embedded.bin檔案所在的位置,二是將embedded.bin載入至記憶體位址為0000:0000的位置,然後從記憶體位址0000:0000的地方開始執行指令。

這段boot code在設計時, 為了簡化程式碼(只能在512bytes以內),有幾個條件限制
1. 只搜尋16筆目錄區中的資料
2. FAT資料區只比對128個index(每個index為4bytes)
3. 有三個數值由BootWriter.exe計算後填入,這三個數值分別為firstDataSec、paraPerClust及            bytesPerClust

另外,要注意以下幾點:
1. BS_OEMName 要填入"MSWIN4.1",否則BIOS會認不得boot sector。至於是認不得,或者是     說不會執行boot code,詳細的細節我並不清楚,我遇到的情況是,在我的筆電(Compaq             Presario V3000)上測試,如果沒有填入"MSWIN4.1",USB Flash Disk就無法開機。
2. USB Flash Disk 的讀取是利用BIOS int 13 function 02的方式,而實際上logical sector 0(所謂       的boot sector)並不等於physical sector 1,必須要加上BPB_HiddSec(隱藏磁區),才是真正對       應到的physical sector
3. 最後,在BIOS的開機設定裡,要將USB DISK enable