2011/12/21

[Linux] Linux 上的 GPIO / I2C 實作筆記之二 概念重提

前言
Linux 上的 GPIO / I2C 其實是很有趣的一個東西,可以用 GPIO 控制的方法去和硬體做溝通。和硬體的溝通比軟體有趣的地方在於馬上就「具現化」在你眼前,所以感覺實在多了,而且也有很多想像的空間。不過,I2C 在 Linux 上的實踐方法其實有兩種: GPIO 拉 I2C 的 protocol 跟 adapter driver 的方式。 I2C 靠 adapter driver 運作的方式我還不會,所以我會談的,都只有用 GPIO 實做 I2C protocol 的方式,這樣的做法其實很多變數在裡面,用到最後會不好整理,不好維護,結果也不夠穩定。不過優點就是在還不了解 linux i2c adapter driver 這一層的時候,不用花多少時間,光靠別的平台的 source code 仿照寫法,就可以開發完成,所以應該可以說是快速開發的方法。

準備材料
在開始工作之前,我們要先了解 GPIO/I2C 的需求:
a. SDA / SCL 兩根 GPIO 的腳位在哪裡。
b. 和 I2C 裝置交談的具體內容 意即是 I2C 裝置的 datasheet

I2C 的交談內容大要
如果把 I2C 簡單化,那麼 I2C 就像是在吟詩一樣,把平當作不動,仄當作腳位拉高再拉低,就會有 平平仄仄仄平平,仄仄平平平仄仄 像這種鬼東西出來。那誰看得懂呢?所以我們先跳過吧。

鬼東西 跳過之後,I2C 的交談內容大致上會是這樣的內容:
[S][Device ID][A][Data][A][Data][N][P]


[S] 代表的意思是 Start ,就是按 I2C protocol 拉一個 Start 。
[Device ID] 就是按 DataSheet 裡頭的說明,拉 Device ID 的值出來。
[A] 就是按 I2C protocol 拉一個 Ack。
[Data] 看 DataSheet 裡面需要送什麼 Data (一開始的 command byte 通常就一個 byte 而已)
[N] 就是按 I2C protocol 拉一個 NAK。
[P] 就是按 I2C protocol 拉一個 Stop。

所以其實很簡單吧? (鬼才相信很簡單,一開始要實作的時候看到這種拉高拉低的,我就開始頭昏眼花了)

因為 I2C 的特性是用一個 Device ID (也就是 Slave Address),做為識別,在同一個 Data Bus 上面進行溝通。因為每一個 Slave Device 的 ID 不一樣,所以在溝通的時候不會發生混亂,可以分時進行。但是每一個 I2C 裝置的交談內容都不大一樣,所以在實作的時候,需要參考各家產品的 data sheet 來進行實作。

在實作的時候因為每個裝置的需要,大致上會有一些名詞:

Config 設定
Polarity 極性
Input 輸入
Output 輸出
Read 讀取
Write 寫入
Register 註冊位址
Command / Control Byte 命令位元
Data Byte 資料位元

你暈了嗎?其實也都還在 [S][Device ID][A][Data][A][Data][N][P] 這個格式裡頭打轉。
執行的順序用人話來說明,大概會是:

1. Config (Initial 這個裝置)
2. Register (說明你要執行或讀寫哪個位址)
3. Control Byte (送出命令)
4. Write Data (寫入資料) 或 Read Data (讀取資料)

別睡,別睡,下文就要開始舉例說明,如何參考一份 datasheet 來開始在 Linux Kernel 上面實作 GPIO / I2C 了:

--
圈重點:
* 所以在溝通的時候,時間差(timer)和延遲(delay)很重要,務必在一開始看 datasheet 的時候就先把時間差先圈出來。

參考資料:
* [Linux] Linux 上的 GPIO / I2C 實作筆記之一 http://antontw.blogspot.com/2011/06/linux-linux-gpio-i2c.html
* 拉平仄 S, P, A, N 什麼鬼的可以參考這裡 I2C 的協定內容 http://en.wikipedia.org/wiki/I%C2%B2C

2011/12/14

[軟體][Linux] SMS 之路 (一) 發送簡訊

前言
最近很忙,所以很久沒寫網誌了,剛剛遇到一點問題,所以想想還是回頭來寫一下筆記。

問題
* Linux 底下如何發送簡訊?

環境配置
* Linux 的開發環境
* 一張 2G/3G 網卡
* 一張可以正常的 SIM 卡

執行動作
* 打開 Linux (不管你是用 vbox/vmware 還是實機的 Linux)
* 把網卡大力插進去

接著應該會在裝置底下看到網卡浮出來:

它有可能長這個樣子,如果你跟我一樣用比較舊的 Kernel ,或著跑到 ttyACM0 如果你的 kernel 很清楚的認為它是 modem 的裝置。

接著就要開始玩弄它了,因為 kernel 把它當成是 serial 的裝置,所以你需要一個 terminal 連接它才能開始跟它溝通。

那麼,我會建議使用:
* putty (linux 版) 初學者建議
* minicom (console 工具) 如果你嫌 GUI 很麻煩的話,建議用這個

putty 選裝置 /dev/ttyUSB3 + serial + baurate (可能是 115200 之類的)
minicom -s 選 serial protocol 調整 device 跟 baurate

接著下來要和 3G網卡/modem 溝通,時間很夠就先把網卡的 AT Command List 看過一遍。
這樣可以發中文簡訊到某人的手機裡:

這樣可以發一堆數字到某人的手機裡:

...
要罵我了嗎?好啦,讓我解釋一下:
AT Command 是和 modem 溝通的指令集,所以下這些 command 可以讓 modem 知道你想做什麼事情。
AT+CMGF=0 代表你想送簡訊的模式是 PDU mode 這個 mode 底下的簡訊是編碼過的,裡頭會帶上 SMS 訊息中心的電話號碼,跟你的訊息本文,還有接受者的電話號碼。
AT+CMGS=22 代表你的訊息本文長度是 22,下面接的那一串就是編碼過後的樣子。

...
嗯,應該還會再罵我一次,因為這樣還是不知道怎麼做 PDU 的編碼。
可以參考一下 http://www.dreamfabric.com/sms 上面有說明 SMS PDU 的編碼格式。

如果你跟我一樣很懶得去看,那這裡也有編碼器

--
參考網址:
* Fred Shell scirpt 發送簡訊 http://fred-zone.blogspot.com/2010/04/blog-post.html
* PDU 編碼參考http://www.dreamfabric.com/sms/
* SMS Tutorial http://www.developershome.com/sms/howToReceiveSMSUsingPC.asp
* SMS 中文編碼 http://en.wikipedia.org/wiki/UTF-16
* AT Command 發送 SMS 的方法 http://www.smssolutions.net/tutorials/gsm/sendsmsat/

[Windows] 好用的小工具: AutoHotKey

做為一個 Linux 的愛好者,轉移到 Windows 上面的時候,往往難以適應 Windows 調整快捷鍵的方式,所以 google 了一下,結果發現很多人愛用的 "Auto Hot key"。不多說,就來給一個範例說明如何使用 Auto Hot key 來...