表 1に使用機器を示す。
表 1 使用機器
名称 |
メーカー |
|
PICkit3 |
microchip |
PIC書き込みツール |
PICkit対応ICSP書き込みアダプターキット |
microchip |
PIC書き込みツール |
PIC16F1827 |
microchip |
PICマイコン |
RN42XVP−I/RM |
microchip |
Bluetoothモジュール |
XBee用2.54mmピッチ変換基板 |
秋月電子 |
|
昇圧型DCDCコンバータ Step UP・DIP 3.3Vタイプ |
秋月電子 |
|
ブレッドボード |
||
ジャンプワイヤー |
本項では使用機器の仕様を示す。図 1にPIC16F1827のピンアサインを示した。頭にRが付くものは入出力ピンである。VSSは電源の+側ピン、VDDは電源の−側ピンである。VPPは書き込みピン、MCLRはマスタークリアリセットピンである。
図 1 DIP型のPIC16F1827のピンアサイン
表 2にPIC16F1827のピン配置を示した。ANSELはアナログ入力ピンと共用となっているピンに関係するものである。A/DはAnalog to Digital Converterである。ReferenceはA/Dの際の基準にする電圧の参照電位を入力するピンである。Cap SenseはCapacitive Sensingの略であり静電容量検知モジュールである。Comparatorは2つの電圧を比較する機能である。SR Latchは様々な能力を組み合わせてSRラッチから出力を得るモジュールである。Timerは数を数える機能である。CCPはCapture/Compare/PWMの略であり、Captureは外部からの信号が入力されたときにタイマー1に値を読み込む機能であり、周波数カウンター等に利用される。Compareは特定の値とタイマー1の値を比較する機能で周期的に割り込みを発生される場合に利用される。PWMは周期的なパルスを発生させる機能で、パルス幅を変化させて外部回路を制御するのに利用される。EUSARTは汎用的なシリアル通信モジュールでTXが送信、RXが受信にあたる。MSSPはSPI、I 2C用の通信機能モジュールである。Interruptは割り込み機能になる。Modulatorは変調機能である。Pull-upはプルアップ抵抗を示している。
表 2 PIC16F1827のピン配置
図 2 RN42XVPのピンアサイン
表 3 各ピンの機能
Pin
|
Signal Name |
Description |
1 |
VDD_3V3 |
3.3 V regulated power input to the module. |
2 |
TXD |
UART TX, 8 mA drive, 3.3-V tolerant. |
3 |
RXD |
UART RX, 3.3 V tolerant. |
4 |
GPIO7 |
GPIO, 24 mA drive, 3.3 V tolerant/ADC input. |
5 |
RESET_N |
Optional module reset signal (active low), 100 k pull up,
|
6 |
GPIO6 |
GPIO, 24 mA drive, 3.3-V tolerant/ADC input. |
7 |
GPIO9 |
GPIO, 24 mA drive, 3.3-V tolerant/ADC input. |
8 |
GPIO4 |
GPIO, 24 mA drive, 3.3-V tolerant/ADC input. |
9 |
GPIO11 |
GPIO, 8 mA drive, 3.3 V tolerant. |
10 |
GND |
Ground. |
11 |
GPIO8 |
GPIO, 8 mA drive, 3.3-V tolerant. The RN41XV and
|
12 |
RTS |
UART RTS flow control, 8 mA drive, 3.3 V tolerant. |
13 |
GPIO2 |
GPIO, 24 mA drive, 3.3 V tolerant/ADC input. |
14 |
Not Used |
No connect. |
15 |
GPIO5 |
GPIO, 24 mA drive, 3.3 V tolerant/ADC input. |
16 |
CTS |
UART CTS flow control, 3.3 V tolerant. |
17 |
GPIO3 |
GPIO, 24 mA drive, 3.3 V tolerant/ADC input. |
18 |
GPIO7 |
GPIO, 24 mA drive, 3.3 V tolerant/ADC input. |
19 |
AIO0 |
|
20 |
AIO1 |
3.1 システム概略図
図 3 システム概要図
図 3にシステム概略を示した。PICのもつA/D変換機能を用いて電圧を測定した。PICはPIC16F1827を使用した。PIC16F1827の使用上0 〜 2.048Vを10bit分解能で測定した。よって2mVの精度で電圧を測定できる。PICで測定した電圧をスマートフォンでモニタリングできるようにする必要があった。BluetoothモジュールをPICと接続した。スマートフォン側でPICが送ったデータを受け取れるようなスマートフォンアプリケーションを作成した。機能として測定した数値を記録し、記録が終わったら特定のメールアドレスへ送信する機能を付けた。
図 4に回路図を示した。Setup・DIPを用いて3Vから3.3Vに昇圧して出力したものをVDDとした。PIC16F1827は18ピンをADコンバータとして電池電圧を測定できるようにリードを出した。また、1ピンと2ピンにLEDと抵抗を繋ぎ、これ通信動作のテスト用とした。PIC16F1827とRN42XVP-I/RMの接続はPIC16F1827の7ピンとRN42XVP-I/RMの2ピン、PIC16F1827の8ピンとRN42XVP-I/RMの3ピンをUSARTのため接続した。
図 4 回路図
図 5にXbee用2.54mmピッチ変換基盤の改造回路を示した。RN42XVP-I/RM はピンピッチが2.0mmなっているが、それに対してブレッドボードやPICのピンピッチで2.54mmである。よってピンピッチを2.0mmから2.54mmに変換する基盤が必要になった。ここで、XBee用2.54mmピッチ変換基盤を使用した。XBee用2.54mmピッチ変換基盤には,IC2に+4V〜20Vの入力電圧を3.3Vに変換する3端子レギュレータが搭載されていた。本項の回路では,電源モジュールとして3.3Vがあるので、この3端子レギュレータをバイパスする必要がある.そこで,図 5に示すIC2を取り外して,図 5のP1とP2を接続した。
図 5 XBee用2.54mmピッチ変化基盤の改造回路図
図 6aに示すXbee用2.54mmピッチ変換基板 AE-Xbee-REG-DIPに実装されているIC2を半田ごてで温めて取り外して,図 6bのようにする.図 6cに示すように,IC2を取り外した基盤の1番ピン(図 5のP1)と3番ピン(図 5のP2)を被覆電線で接続するようにはんだ付けする.
図 6 XBee用2.54mmピッチ変換基盤のBluetoothモジュール対応改造手順
3.3 Bluetoothモジュールの設定
Bluetoothモジュールを設定する際には、Bluetooth接続ができるパソコンとソフトウェアとして「Teraterm」(http://sourceforge.jp/projects/ttssh2/)を準備した。
パソコンがBluetooth接続できない場合はUSBのBluetoothドングルを使用するとBluetooth接続できるようになる。BluetoothにVDDとGNDを繋いで電源を入れるとRN42XVPの赤色と緑色のLEDが点灯する。
Windows8でBluetoothの設定方法を示す。Bluetoothの設定画面を開き「RN42…」を選択する。その後Tera termを起動してシリアル接続を選択してCOM3のBluetoothを選択して接続する。このとき接続できない場合はもう一度Bluetoothの設定画面を開き一度デバイスの削除をして同じデバイスを再び接続する。このときのPINコードを求められるので「1234」と入力した。Tera termを再起動して再び接続した。ウィンドウの文字が接続中から変わった。後に「$$$」と入力してエンターを押す。Tera termのウィンドウにCMDと表示されRN42XVPの緑色のLEDの点滅が早くなればRN42XVPがコマンドモードになっている。入力したコマンドを下に示す。
表 4 Bluetoothモジュールのコマンド
コマンド |
コマンド内容 |
$$$ |
コマンドモード開始 |
SN,<string> |
デバイスネームを<string>にする |
SP,<string> |
PINコードを<string>にする |
SU,<value> |
通信速度を<value>にする |
SA,<value> |
<value>のモードに設定する
|
R,1 |
再起動 |
D |
基本設定を表示する |
E |
拡張設定表示する |
SN,BTC001 モジュールの名前をBTC001にする
SP,3573 PINコードを3573にする
SU,1152000接続速度を115200bpsにする
SA,4 PINコードを使えるようにする
R.1 リブート
D 設定一覧
E 細かい設定一覧
図 7にPICプログラムのアルゴリズムを示した。ひし形ダイアグラムでは判断を行うダイアグラムでYesの場合下に進み、Noの場合右へ進む。2個の六角形のダイアグラム間でループ動作を行う。上のダイアグラムの数値は「変数 = 初期値,終値,増分値」となっている。これらを元にプログラムを作成した。
図 7にsystem.hのソースを、図 8にuser.hのソースを、図 9にmain.cのソースを示した。System.hはPICの設定を、user.hにはプログラムで使う定義を、main.cにはPICが実際に行う動作を書き込んだ。
図 7 PICプログラムのアルゴリズム
1 |
#include <xc.h> |
2 |
|
3 |
#pragma config FOSC = INTOSC |
4 |
#pragma config WDTE = OFF |
5 |
#pragma config PWRTE = ON |
6 |
#pragma config MCLRE = ON |
7 |
#pragma config CP = OFF |
8 |
#pragma config CPD = OFF |
9 |
#pragma config BOREN = ON |
10 |
#pragma config CLKOUTEN = ON |
11 |
#pragma config IESO = OFF |
12 |
#pragma config FCMEN = OFF |
13 |
#pragma config WRT = OFF |
14 |
#pragma config PLLEN = ON |
15 |
#pragma config STVREN = OFF |
16 |
#pragma config BORV = LO |
17 |
#pragma config LVP = ON |
18 |
|
19 |
#define Fosc 32 |
図 8 system.h
1 |
void InitApp(void); |
2 |
|
3 |
unsigned char RcvFlag; |
4 |
unsigned char RcvBuf[32],SndBuf[32],Buffer[32]; |
5 |
int Index; |
6 |
#define Max_Size 32 |
7 |
|
8 |
unsigned char msg1[] = "$$$"; |
9 |
unsigned char msg2[] = "SF,1\r"; |
10 |
unsigned char msg3[] = "SN,BT_PIO\r"; |
11 |
unsigned char msg4[] = "SA,4\r"; |
12 |
unsigned char msg5[] = "R,1\r"; |
13 |
|
14 |
unsigned char getcUSART (void); |
15 |
void Send(unsigned char txchar); |
16 |
void SendStr(unsigned char * str); |
17 |
void SendCmd(const unsigned char *cmd); |
18 |
void RcvDisp(void); |
19 |
void Process(void); |
20 |
void delay_us(unsigned int usec); |
21 |
void delay_ms(unsigned int msec); |
22 |
void TRStart(void); |
23 |
int GetADC(int ch); |
図 9 user.h
1 |
#if defined(__XC) |
2 |
#include <xc.h> |
3 |
#elif defined(HI_TECH_C) |
4 |
#include <htc.h> |
5 |
#endif |
6 |
|
7 |
#include <stdint.h> |
8 |
#include <stdbool.h> |
9 |
|
10 |
#include "system.h" |
11 |
#include "user.h" |
12 |
|
13 |
int main(void){ |
14 |
OSCCON = 0xF0; |
15 |
ANSELA = 0x03; |
16 |
ANSELB = 0; |
17 |
FVRCON = 0xC2; |
18 |
TRISA = 0x23; |
19 |
TRISB = 0xDA; |
20 |
WPUB = 0x18; |
21 |
OPTION_REGbits.nWPUEN = 0; |
22 |
LATBbits.LATB0 = 0; |
23 |
delay_ms(100); |
24 |
LATBbits.LATB0 = 1; |
25 |
delay_ms(500); |
26 |
TXSTA = 0x24; |
27 |
RCSTA = 0x90; |
28 |
BAUDCON=0x08; |
29 |
SPBRG = 68; |
30 |
if(PORTBbits.RB3 == 0){ |
31 |
SendCmd(msg1); |
32 |
SendCmd(msg2); |
33 |
SendCmd(msg3); |
34 |
SendCmd(msg4); |
35 |
SendCmd(msg5); |
36 |
} |
37 |
|
38 |
TXSTA = 0x24; |
39 |
RCSTA = 0x90; |
40 |
ADCON0 = 0; |
41 |
ADCON1 = 0xE3; |
42 |
Index = 0; |
43 |
RcvFlag = 0; |
44 |
PIR1bits.RCIF = 0; |
45 |
PIE1bits.RCIE = 1; |
46 |
INTCONbits.PEIE = 1; |
47 |
INTCONbits.GIE = 1; |
48 |
while(1){ |
49 |
if(RcvFlag){ |
50 |
RcvFlag = 0; |
51 |
if((Buffer[0] == 'S')){ |
52 |
SndBuf[0] = 'M'; |
53 |
SndBuf[1] = Buffer[1]; |
54 |
Process(); |
55 |
Index = 0; |
56 |
} |
57 |
} |
58 |
} |
59 |
} |
60 |
|
61 |
void Process(void){ |
62 |
int data; |
63 |
int n; |
64 |
int m; |
65 |
switch(Buffer[1]){ |
66 |
case 'B': |
67 |
SndBuf[2] = (PORTAbits.RA2 == 0) ? '0' : '1'; |
68 |
SndBuf[3] = (PORTAbits.RA3 == 0) ? '0' : '1'; |
69 |
SndBuf[4] = (PORTAbits.RA4 == 0) ? '0' : '1'; |
70 |
SndBuf[5] = (PORTAbits.RA5 == 0) ? '0' : '1'; |
71 |
SndBuf[6] = (unsigned char)0x40; |
72 |
SndBuf[7] = (unsigned char)0x40; |
73 |
data = GetADC(1); |
74 |
SndBuf[8] = (unsigned char)(data / 32)+0x40; |
75 |
SndBuf[9] = (unsigned char)(data % 32)+0x40; |
76 |
SndBuf[10] = 'E'; |
77 |
SendStr(SndBuf); |
78 |
break; |
79 |
case 'T': |
80 |
for(n = 0; n < 10; n++){ |
81 |
m = n * 1000; |
82 |
delay_ms(m); |
83 |
SndBuf[2] = (unsigned char)(n / 32)+0x40; |
84 |
SndBuf[3] = (unsigned char)(n % 32)+0x40; |
85 |
SndBuf[4] = 0; |
86 |
SndBuf[5] = 0; |
87 |
SndBuf[6] = 0; |
88 |
SndBuf[7] = 0; |
89 |
data = GetADC(1); |
90 |
SndBuf[8] = (unsigned char)(data / 32)+0x40; |
91 |
SndBuf[9] = (unsigned char)(data % 32)+0x40; |
92 |
SndBuf[10] = 'E'; |
93 |
SendStr(SndBuf); |
94 |
} |
95 |
break; |
96 |
case 'C': |
97 |
|
98 |
switch(Buffer[2]){ |
99 |
case '1': |
100 |
LATAbits.LATA2 = (Buffer[3] == '1') ? 1 : 0; |
101 |
break; |
102 |
case '2': |
103 |
LATAbits.LATA3 = (Buffer[3] == '1') ? 1 : 0; |
104 |
break; |
105 |
default: break; |
106 |
} |
107 |
break; |
108 |
default: break; |
109 |
} |
110 |
} |
111 |
void interrupt isr(void){ |
112 |
unsigned char data; |
113 |
int i; |
114 |
if(PIR1bits.RCIF){ |
115 |
PIR1bits.RCIF = 0; |
116 |
if((RCSTAbits.OERR) || (RCSTAbits.FERR)){ |
117 |
data = RCREG; |
118 |
RCSTA = 0; |
119 |
RCSTA = 0x90; |
120 |
} |
121 |
else{ |
122 |
if(Index < Max_Size){ |
123 |
data = RCREG; |
124 |
if(data == 'S') |
125 |
Index = 0; |
126 |
RcvBuf[Index] = data; |
127 |
if(RcvBuf[Index] == 'E'){ |
128 |
i = 0; |
129 |
while(i <= Index){ |
130 |
Buffer[i] = RcvBuf[i]; |
131 |
i++; |
132 |
} |
133 |
RcvFlag = 1; |
134 |
} |
135 |
Index++; |
136 |
} |
137 |
else{ |
138 |
data = RCREG; |
139 |
Index = 0; |
140 |
} |
141 |
} |
142 |
} |
143 |
} |
144 |
|
145 |
void Send(unsigned char txchar){ |
146 |
while(!TXSTAbits.TRMT); |
147 |
TXREG = txchar; |
148 |
} |
149 |
void SendStr(unsigned char * str){ |
150 |
int i; |
151 |
|
152 |
for(i= 0; i<Max_Size; i++) |
153 |
Send(*str++); |
154 |
} |
155 |
|
156 |
void SendCmd(const unsigned char *cmd){ |
157 |
while(*cmd != 0) |
158 |
Send(*cmd++); |
159 |
delay_ms(1000); |
160 |
} |
161 |
int GetADC(int ch){ |
162 |
int value; |
163 |
ADCON0 = (ch << 2) + 0x01; |
164 |
delay_us(20); |
165 |
ADCON0bits.GO = 1; |
166 |
while(ADCON0bits.GO); |
167 |
value = ADRESL+(ADRESH*256); |
168 |
return(value); |
169 |
} |
170 |
void delay_us(unsigned int usec){ |
171 |
unsigned int Max, k; |
172 |
Max = usec * Fosc/30; |
173 |
for (k=0;k<Max;k++) |
174 |
{ } |
175 |
} |
176 |
void delay_ms(unsigned int msec){ |
177 |
int j; |
178 |
for(j=0; j<msec; j++) |
179 |
delay_us(1000); |
180 |
} |
3.5 スマートフォンアプリケーションのプログラム
1 |
package com.takkyo.android.BluetoothChat; |
2 |
|
3 |
import java.io.*; |
4 |
import android.app.ActionBar; |
5 |
import android.app.Activity; |
6 |
import android.bluetooth.BluetoothAdapter; |
7 |
import android.bluetooth.BluetoothDevice; |
8 |
import android.content.Context; |
9 |
import android.content.Intent; |
10 |
import android.net.Uri; |
11 |
import android.os.Bundle; |
12 |
import android.os.Environment; |
13 |
import android.os.Handler; |
14 |
import android.os.Message; |
15 |
import android.text.format.Time; |
16 |
import android.util.Log; |
17 |
import android.view.KeyEvent; |
18 |
import android.view.Menu; |
19 |
import android.view.MenuInflater; |
20 |
import android.view.MenuItem; |
21 |
import android.view.View; |
22 |
import android.view.Window; |
23 |
import android.view.View.OnClickListener; |
24 |
import android.view.inputmethod.EditorInfo; |
25 |
import android.widget.ArrayAdapter; |
26 |
import android.widget.Button; |
27 |
import android.widget.EditText; |
28 |
import android.widget.ListView; |
29 |
import android.widget.TextView; |
30 |
import android.widget.Toast; |
31 |
|
32 |
public class BluetoothChat extends Activity { |
33 |
private static final String TAG = "BluetoothChat"; |
34 |
private static final boolean D = true; |
35 |
public static final int MESSAGE_STATE_CHANGE = 1; |
36 |
public static final int MESSAGE_READ = 2; |
37 |
public static final int MESSAGE_WRITE = 3; |
38 |
public static final int MESSAGE_DEVICE_NAME = 4; |
39 |
public static final int MESSAGE_TOAST = 5; |
40 |
public static final String DEVICE_NAME = "device_name"; |
41 |
public static final String TOAST = "toast"; |
42 |
private static final int REQUEST_CONNECT_DEVICE_SECURE = 1; |
43 |
private static final int REQUEST_CONNECT_DEVICE_INSECURE = 2; |
44 |
private static final int REQUEST_ENABLE_BT = 3; |
45 |
private ListView mConversationView; |
46 |
private EditText mOutEditText; |
47 |
private Button mSendButton; |
48 |
private Button oSendButton; |
49 |
private String mConnectedDeviceName = null; |
50 |
private ArrayAdapter<String> mConversationArrayAdapter; |
51 |
private StringBuffer mOutStringBuffer; |
52 |
private BluetoothAdapter mBluetoothAdapter = null; |
53 |
private BluetoothChatService mChatService = null; |
54 |
private static int Data1 , Data2 , Data3 , Data4; |
55 |
|
56 |
@Override |
57 |
public void onCreate(Bundle savedInstanceState) { |
58 |
super.onCreate(savedInstanceState); |
59 |
if(D) Log.e(TAG, "+++ ON CREATE +++"); |
60 |
|
61 |
setContentView(R.layout.main); |
62 |
|
63 |
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); |
64 |
|
65 |
if (mBluetoothAdapter == null) { |
66 |
Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show(); |
67 |
finish(); |
68 |
return; |
69 |
} |
70 |
} |
71 |
|
72 |
@Override |
73 |
public void onStart() { |
74 |
super.onStart(); |
75 |
if(D) Log.e(TAG, "++ ON START ++"); |
76 |
|
77 |
if (!mBluetoothAdapter.isEnabled()) { |
78 |
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); |
79 |
startActivityForResult(enableIntent, REQUEST_ENABLE_BT); |
80 |
} else { |
81 |
if (mChatService == null) setupChat(); |
82 |
} |
83 |
} |
84 |
|
85 |
@Override |
86 |
public synchronized void onResume() { |
87 |
super.onResume(); |
88 |
if(D) Log.e(TAG, "+ ON RESUME +"); |
89 |
|
90 |
if (mChatService != null) { |
91 |
if (mChatService.getState() == BluetoothChatService.STATE_NONE) { |
92 |
mChatService.start(); |
93 |
} |
94 |
} |
95 |
} |
96 |
|
97 |
private void setupChat() { |
98 |
Log.d(TAG, "setupChat()"); |
99 |
|
100 |
mConversationArrayAdapter = new ArrayAdapter<String>(this, R.layout.message); |
101 |
mConversationView = (ListView) findViewById(R.id.in); |
102 |
mConversationView.setAdapter(mConversationArrayAdapter); |
103 |
|
104 |
mOutEditText = (EditText) findViewById(R.id.edit_text_out); |
105 |
mOutEditText.setOnEditorActionListener(mWriteListener); |
106 |
|
107 |
mSendButton = (Button) findViewById(R.id.button_send); |
108 |
mSendButton.setOnClickListener(new OnClickListener() { |
109 |
public void onClick(View v) { |
110 |
TextView view = (TextView) findViewById(R.id.edit_text_out); |
111 |
String message = "STE"; |
112 |
sendMessage(message); |
113 |
} |
114 |
}); |
115 |
|
116 |
oSendButton = (Button) findViewById(R.id.Button_onetime); |
117 |
oSendButton.setOnClickListener(new OnClickListener() { |
118 |
public void onClick(View v) { |
119 |
TextView view = (TextView) findViewById(R.id.edit_text_out); |
120 |
String message = view.getText().toString(); |
121 |
sendMessage(message); |
122 |
} |
123 |
}); |
124 |
|
125 |
mChatService = new BluetoothChatService(this, mHandler); |
126 |
|
127 |
mOutStringBuffer = new StringBuffer(""); |
128 |
} |
129 |
|
130 |
@Override |
131 |
public synchronized void onPause() { |
132 |
super.onPause(); |
133 |
if(D) Log.e(TAG, "- ON PAUSE -"); |
134 |
} |
135 |
|
136 |
@Override |
137 |
public void onStop() { |
138 |
super.onStop(); |
139 |
if(D) Log.e(TAG, "-- ON STOP --"); |
140 |
} |
141 |
|
142 |
@Override |
143 |
public void onDestroy() { |
144 |
super.onDestroy(); |
145 |
if (mChatService != null) mChatService.stop(); |
146 |
if(D) Log.e(TAG, "--- ON DESTROY ---"); |
147 |
} |
148 |
|
149 |
private void ensureDiscoverable() { |
150 |
if(D) Log.d(TAG, "ensure discoverable"); |
151 |
if (mBluetoothAdapter.getScanMode() != |
152 |
BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) { |
153 |
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); |
154 |
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300); |
155 |
startActivity(discoverableIntent); |
156 |
} |
157 |
} |
158 |
|
159 |
private void sendMessage(String message) { |
160 |
if (mChatService.getState() != BluetoothChatService.STATE_CONNECTED) { |
161 |
Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT).show(); |
162 |
return; |
163 |
} |
164 |
|
165 |
if (message.length() > 0) { |
166 |
byte[] send = message.getBytes(); |
167 |
mChatService.write(send); |
168 |
|
169 |
mOutStringBuffer.setLength(0); |
170 |
mOutEditText.setText(mOutStringBuffer); |
171 |
} |
172 |
} |
173 |
|
174 |
private TextView.OnEditorActionListener mWriteListener = |
175 |
new TextView.OnEditorActionListener() { |
176 |
public boolean onEditorAction(TextView view, int actionId, KeyEvent event) { |
177 |
if (actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_UP) { |
178 |
String message = view.getText().toString(); |
179 |
sendMessage(message); |
180 |
} |
181 |
if(D) Log.i(TAG, "END onEditorAction"); |
182 |
return true; |
183 |
} |
184 |
}; |
185 |
|
186 |
private final void setStatus(int resId) { |
187 |
final ActionBar actionBar = getActionBar(); |
188 |
actionBar.setSubtitle(resId); |
189 |
} |
190 |
|
191 |
private final void setStatus(CharSequence subTitle) { |
192 |
final ActionBar actionBar = getActionBar(); |
193 |
actionBar.setSubtitle(subTitle); |
194 |
} |
195 |
|
196 |
private final Handler mHandler = new Handler() { |
197 |
@Override |
198 |
public void handleMessage(Message msg) { |
199 |
switch (msg.what) { |
200 |
case MESSAGE_STATE_CHANGE: |
201 |
if(D) Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1); |
202 |
switch (msg.arg1) { |
203 |
case BluetoothChatService.STATE_CONNECTED: |
204 |
setStatus(getString(R.string.title_connected_to, mConnectedDeviceName)); |
205 |
mConversationArrayAdapter.clear(); |
206 |
break; |
207 |
case BluetoothChatService.STATE_CONNECTING: |
208 |
setStatus(R.string.title_connecting); |
209 |
break; |
210 |
case BluetoothChatService.STATE_LISTEN: |
211 |
case BluetoothChatService.STATE_NONE: |
212 |
setStatus(R.string.title_not_connected); |
213 |
break; |
214 |
} |
215 |
break; |
216 |
case MESSAGE_WRITE: |
217 |
byte[] writeBuf = (byte[]) msg.obj; |
218 |
String writeMessage = new String(writeBuf); |
219 |
if(writeMessage.equals("STE")){ |
220 |
mConversationArrayAdapter.add("Me: 測定開始" ); |
221 |
}else if(writeMessage.equals("SBE")){ |
222 |
mConversationArrayAdapter.add("Me: 一回だけ測定"); |
223 |
}else{ |
224 |
mConversationArrayAdapter.add("Me: " + writeMessage); |
225 |
} |
226 |
break; |
227 |
case MESSAGE_READ: |
228 |
byte[] readBuf = (byte[])msg.obj; |
229 |
Data1 = (readBuf[8]-0x40)*32 + readBuf[9]-0x40; |
230 |
Data2 = (readBuf[2]-0x40)*32 + readBuf[3]-0x40; |
231 |
Data3 = readBuf[1]; //STE=84 SBE=66 |
232 |
Data1 = Data1*2; |
233 |
|
234 |
|
235 |
String readMessage = Integer.toString(Data1); |
236 |
String readMessage2 = Integer.toString(Data2); |
237 |
File fpath = new File(Environment.getExternalStorageDirectory()+"/Android/data/" + getPackageName() + "/files/" ); |
238 |
|
239 |
mConversationArrayAdapter.add(mConnectedDeviceName+": " + readMessage + "," + readMessage2); |
240 |
if(Data2 == 9){ |
241 |
} |
242 |
break; |
243 |
case MESSAGE_DEVICE_NAME: |
244 |
mConnectedDeviceName = msg.getData().getString(DEVICE_NAME); |
245 |
Toast.makeText(getApplicationContext(), "Connected to " |
246 |
+ mConnectedDeviceName, Toast.LENGTH_SHORT).show(); |
247 |
break; |
248 |
case MESSAGE_TOAST: |
249 |
Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST), |
250 |
Toast.LENGTH_SHORT).show(); |
251 |
break; |
252 |
} |
253 |
} |
254 |
}; |
255 |
|
256 |
public void onActivityResult(int requestCode, int resultCode, Intent data) { |
257 |
if(D) Log.d(TAG, "onActivityResult " + resultCode); |
258 |
switch (requestCode) { |
259 |
case REQUEST_CONNECT_DEVICE_SECURE: |
260 |
if (resultCode == Activity.RESULT_OK) { |
261 |
connectDevice(data, true); |
262 |
} |
263 |
break; |
264 |
case REQUEST_CONNECT_DEVICE_INSECURE: |
265 |
if (resultCode == Activity.RESULT_OK) { |
266 |
connectDevice(data, false); |
267 |
} |
268 |
break; |
269 |
case REQUEST_ENABLE_BT: |
270 |
if (resultCode == Activity.RESULT_OK) { |
271 |
setupChat(); |
272 |
} else { |
273 |
Log.d(TAG, "BT not enabled"); |
274 |
Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show(); |
275 |
finish(); |
276 |
} |
277 |
} |
278 |
} |
279 |
|
280 |
private void connectDevice(Intent data, boolean secure) { |
281 |
String address = data.getExtras() |
282 |
.getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS); |
283 |
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address); |
284 |
mChatService.connect(device, secure); |
285 |
} |
286 |
|
287 |
@Override |
288 |
public boolean onCreateOptionsMenu(Menu menu) { |
289 |
MenuInflater inflater = getMenuInflater(); |
290 |
inflater.inflate(R.menu.option_menu, menu); |
291 |
return true; |
292 |
} |
293 |
|
294 |
@Override |
295 |
public boolean onOptionsItemSelected(MenuItem item) { |
296 |
Intent serverIntent = null; |
297 |
switch (item.getItemId()) { |
298 |
case R.id.secure_connect_scan: |
299 |
serverIntent = new Intent(this, DeviceListActivity.class); |
300 |
startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_SECURE); |
301 |
return true; |
302 |
case R.id.insecure_connect_scan: |
303 |
serverIntent = new Intent(this, DeviceListActivity.class); |
304 |
startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_INSECURE); |
305 |
return true; |
306 |
case R.id.discoverable: |
307 |
ensureDiscoverable(); |
308 |
return true; |
309 |
} |
310 |
return false; |
311 |
} |
312 |
|
313 |
public void send(String s, String t){ |
314 |
} |
315 |
|
316 |
} |
図 11 BluetoothChat.java
1 |
package com.takkyo.android.BluetoothChat; |
2 |
|
3 |
import java.io.IOException; |
4 |
import java.io.InputStream; |
5 |
import java.io.OutputStream; |
6 |
import java.util.UUID; |
7 |
|
8 |
import android.bluetooth.BluetoothAdapter; |
9 |
import android.bluetooth.BluetoothDevice; |
10 |
import android.bluetooth.BluetoothServerSocket; |
11 |
import android.bluetooth.BluetoothSocket; |
12 |
import android.content.Context; |
13 |
import android.os.Bundle; |
14 |
import android.os.Handler; |
15 |
import android.os.Message; |
16 |
import android.util.Log; |
17 |
|
18 |
public class BluetoothChatService { |
19 |
private static final String TAG = "BluetoothChatService"; |
20 |
private static final boolean D = true; |
21 |
|
22 |
private static final String NAME_SECURE = "BluetoothChatSecure"; |
23 |
private static final String NAME_INSECURE = "BluetoothChatInsecure"; |
24 |
|
25 |
private static final UUID MY_UUID_SECURE = |
26 |
UUID.fromString("00001101-0000-1000-8000-0805F9B34FB"); |
27 |
private static final UUID MY_UUID_INSECURE = |
28 |
UUID.fromString("8ce255c0-200a-11e0-ac64-0800200c9a66"); |
29 |
|
30 |
public static final int Max_Size = 32; |
31 |
private final BluetoothAdapter mAdapter; |
32 |
private final Handler mHandler; |
33 |
private AcceptThread mSecureAcceptThread; |
34 |
private AcceptThread mInsecureAcceptThread; |
35 |
private ConnectThread mConnectThread; |
36 |
private ConnectedThread mConnectedThread; |
37 |
private int mState; |
38 |
|
39 |
public static final int STATE_NONE = 0; // we're doing nothing |
40 |
public static final int STATE_LISTEN = 1; // now listening for incoming connections |
41 |
public static final int STATE_CONNECTING = 2; // now initiating an outgoing connection |
42 |
public static final int STATE_CONNECTED = 3; // now connected to a remote device |
43 |
|
44 |
public BluetoothChatService(Context context, Handler handler) { |
45 |
mAdapter = BluetoothAdapter.getDefaultAdapter(); |
46 |
mState = STATE_NONE; |
47 |
mHandler = handler; |
48 |
} |
49 |
|
50 |
private synchronized void setState(int state) { |
51 |
if (D) Log.d(TAG, "setState() " + mState + " -> " + state); |
52 |
mState = state; |
53 |
|
54 |
mHandler.obtainMessage(BluetoothChat.MESSAGE_STATE_CHANGE, state, -1).sendToTarget(); |
55 |
} |
56 |
|
57 |
public synchronized int getState() { |
58 |
return mState; |
59 |
} |
60 |
|
61 |
public synchronized void start() { |
62 |
if (D) Log.d(TAG, "start"); |
63 |
|
64 |
if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;} |
65 |
|
66 |
if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;} |
67 |
|
68 |
setState(STATE_LISTEN); |
69 |
|
70 |
if (mSecureAcceptThread == null) { |
71 |
mSecureAcceptThread = new AcceptThread(true); |
72 |
mSecureAcceptThread.start(); |
73 |
} |
74 |
if (mInsecureAcceptThread == null) { |
75 |
mInsecureAcceptThread = new AcceptThread(false); |
76 |
mInsecureAcceptThread.start(); |
77 |
} |
78 |
} |
79 |
|
80 |
public synchronized void connect(BluetoothDevice device, boolean secure) { |
81 |
if (D) Log.d(TAG, "connect to: " + device); |
82 |
|
83 |
if (mState == STATE_CONNECTING) { |
84 |
if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;} |
85 |
} |
86 |
|
87 |
if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;} |
88 |
|
89 |
mConnectThread = new ConnectThread(device, secure); |
90 |
mConnectThread.start(); |
91 |
setState(STATE_CONNECTING); |
92 |
} |
93 |
|
94 |
public synchronized void connected(BluetoothSocket socket, BluetoothDevice |
95 |
device, final String socketType) { |
96 |
if (D) Log.d(TAG, "connected, Socket Type:" + socketType); |
97 |
|
98 |
if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;} |
99 |
|
100 |
if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;} |
101 |
|
102 |
if (mSecureAcceptThread != null) { |
103 |
mSecureAcceptThread.cancel(); |
104 |
mSecureAcceptThread = null; |
105 |
} |
106 |
if (mInsecureAcceptThread != null) { |
107 |
mInsecureAcceptThread.cancel(); |
108 |
mInsecureAcceptThread = null; |
109 |
} |
110 |
|
111 |
mConnectedThread = new ConnectedThread(socket, socketType); |
112 |
mConnectedThread.start(); |
113 |
|
114 |
Message msg = mHandler.obtainMessage(BluetoothChat.MESSAGE_DEVICE_NAME); |
115 |
Bundle bundle = new Bundle(); |
116 |
bundle.putString(BluetoothChat.DEVICE_NAME, device.getName()); |
117 |
msg.setData(bundle); |
118 |
mHandler.sendMessage(msg); |
119 |
|
120 |
setState(STATE_CONNECTED); |
121 |
} |
122 |
|
123 |
public synchronized void stop() { |
124 |
if (D) Log.d(TAG, "stop"); |
125 |
|
126 |
if (mConnectThread != null) { |
127 |
mConnectThread.cancel(); |
128 |
mConnectThread = null; |
129 |
} |
130 |
|
131 |
if (mConnectedThread != null) { |
132 |
mConnectedThread.cancel(); |
133 |
mConnectedThread = null; |
134 |
} |
135 |
|
136 |
if (mSecureAcceptThread != null) { |
137 |
mSecureAcceptThread.cancel(); |
138 |
mSecureAcceptThread = null; |
139 |
} |
140 |
|
141 |
if (mInsecureAcceptThread != null) { |
142 |
mInsecureAcceptThread.cancel(); |
143 |
mInsecureAcceptThread = null; |
144 |
} |
145 |
setState(STATE_NONE); |
146 |
} |
147 |
|
148 |
public void write(byte[] out) { |
149 |
ConnectedThread r; |
150 |
synchronized (this) { |
151 |
if (mState != STATE_CONNECTED) return; |
152 |
r = mConnectedThread; |
153 |
} |
154 |
r.write(out); |
155 |
} |
156 |
|
157 |
private void connectionFailed() { |
158 |
Message msg = mHandler.obtainMessage(BluetoothChat.MESSAGE_TOAST); |
159 |
Bundle bundle = new Bundle(); |
160 |
bundle.putString(BluetoothChat.TOAST, "Unable to connect device"); |
161 |
msg.setData(bundle); |
162 |
mHandler.sendMessage(msg); |
163 |
|
164 |
BluetoothChatService.this.start(); |
165 |
} |
166 |
|
167 |
private void connectionLost() { |
168 |
Message msg = mHandler.obtainMessage(BluetoothChat.MESSAGE_TOAST); |
169 |
Bundle bundle = new Bundle(); |
170 |
bundle.putString(BluetoothChat.TOAST, "Device connection was lost"); |
171 |
msg.setData(bundle); |
172 |
mHandler.sendMessage(msg); |
173 |
|
174 |
BluetoothChatService.this.start(); |
175 |
} |
176 |
|
177 |
private class AcceptThread extends Thread { |
178 |
private final BluetoothServerSocket mmServerSocket; |
179 |
private String mSocketType; |
180 |
|
181 |
public AcceptThread(boolean secure) { |
182 |
BluetoothServerSocket tmp = null; |
183 |
mSocketType = secure ? "Secure":"Insecure"; |
184 |
|
185 |
try { |
186 |
if (secure) { |
187 |
tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE, |
188 |
MY_UUID_SECURE); |
189 |
} else { |
190 |
tmp = mAdapter.listenUsingInsecureRfcommWithServiceRecord( |
191 |
NAME_INSECURE, MY_UUID_INSECURE); |
192 |
} |
193 |
} catch (IOException e) { |
194 |
Log.e(TAG, "Socket Type: " + mSocketType + "listen() failed", e); |
195 |
} |
196 |
mmServerSocket = tmp; |
197 |
} |
198 |
|
199 |
public void run() { |
200 |
if (D) Log.d(TAG, "Socket Type: " + mSocketType + |
201 |
"BEGIN mAcceptThread" + this); |
202 |
setName("AcceptThread" + mSocketType); |
203 |
|
204 |
BluetoothSocket socket = null; |
205 |
|
206 |
while (mState != STATE_CONNECTED) { |
207 |
try { |
208 |
socket = mmServerSocket.accept(); |
209 |
} catch (IOException e) { |
210 |
Log.e(TAG, "Socket Type: " + mSocketType + "accept() failed", e); |
211 |
break; |
212 |
} |
213 |
|
214 |
if (socket != null) { |
215 |
synchronized (BluetoothChatService.this) { |
216 |
switch (mState) { |
217 |
case STATE_LISTEN: |
218 |
case STATE_CONNECTING: |
219 |
connected(socket, socket.getRemoteDevice(), |
220 |
mSocketType); |
221 |
break; |
222 |
case STATE_NONE: |
223 |
case STATE_CONNECTED: |
224 |
try { |
225 |
socket.close(); |
226 |
} catch (IOException e) { |
227 |
Log.e(TAG, "Could not close unwanted socket", e); |
228 |
} |
229 |
break; |
230 |
} |
231 |
} |
232 |
} |
233 |
} |
234 |
if (D) Log.i(TAG, "END mAcceptThread, socket Type: " + mSocketType); |
235 |
|
236 |
} |
237 |
|
238 |
public void cancel() { |
239 |
if (D) Log.d(TAG, "Socket Type" + mSocketType + "cancel " + this); |
240 |
try { |
241 |
mmServerSocket.close(); |
242 |
} catch (IOException e) { |
243 |
Log.e(TAG, "Socket Type" + mSocketType + "close() of server failed", e); |
244 |
} |
245 |
} |
246 |
} |
247 |
|
248 |
|
249 |
private class ConnectThread extends Thread { |
250 |
private final BluetoothSocket mmSocket; |
251 |
private final BluetoothDevice mmDevice; |
252 |
private String mSocketType; |
253 |
|
254 |
public ConnectThread(BluetoothDevice device, boolean secure) { |
255 |
mmDevice = device; |
256 |
BluetoothSocket tmp = null; |
257 |
mSocketType = secure ? "Secure" : "Insecure"; |
258 |
|
259 |
try { |
260 |
if (secure) { |
261 |
tmp = device.createRfcommSocketToServiceRecord( |
262 |
MY_UUID_SECURE); |
263 |
} else { |
264 |
tmp = device.createInsecureRfcommSocketToServiceRecord( |
265 |
MY_UUID_INSECURE); |
266 |
} |
267 |
} catch (IOException e) { |
268 |
Log.e(TAG, "Socket Type: " + mSocketType + "create() failed", e); |
269 |
} |
270 |
mmSocket = tmp; |
271 |
} |
272 |
|
273 |
public void run() { |
274 |
Log.i(TAG, "BEGIN mConnectThread SocketType:" + mSocketType); |
275 |
setName("ConnectThread" + mSocketType); |
276 |
|
277 |
mAdapter.cancelDiscovery(); |
278 |
|
279 |
try { |
280 |
mmSocket.connect(); |
281 |
} catch (IOException e) { |
282 |
try { |
283 |
mmSocket.close(); |
284 |
} catch (IOException e2) { |
285 |
Log.e(TAG, "unable to close() " + mSocketType + |
286 |
" socket during connection failure", e2); |
287 |
} |
288 |
connectionFailed(); |
289 |
return; |
290 |
} |
291 |
|
292 |
synchronized (BluetoothChatService.this) { |
293 |
mConnectThread = null; |
294 |
} |
295 |
|
296 |
connected(mmSocket, mmDevice, mSocketType); |
297 |
} |
298 |
|
299 |
public void cancel() { |
300 |
try { |
301 |
mmSocket.close(); |
302 |
} catch (IOException e) { |
303 |
Log.e(TAG, "close() of connect " + mSocketType + " socket failed", e); |
304 |
} |
305 |
} |
306 |
} |
307 |
|
308 |
private class ConnectedThread extends Thread { |
309 |
private final BluetoothSocket mmSocket; |
310 |
private final InputStream mmInStream; |
311 |
private final OutputStream mmOutStream; |
312 |
|
313 |
public ConnectedThread(BluetoothSocket socket, String socketType) { |
314 |
Log.d(TAG, "create ConnectedThread: " + socketType); |
315 |
mmSocket = socket; |
316 |
InputStream tmpIn = null; |
317 |
OutputStream tmpOut = null; |
318 |
|
319 |
try { |
320 |
tmpIn = socket.getInputStream(); |
321 |
tmpOut = socket.getOutputStream(); |
322 |
} catch (IOException e) { |
323 |
Log.e(TAG, "temp sockets not created", e); |
324 |
} |
325 |
|
326 |
mmInStream = tmpIn; |
327 |
mmOutStream = tmpOut; |
328 |
} |
329 |
public void run() { |
330 |
|
331 |
Log.i(TAG, "BEGIN mConnectedThread"); |
332 |
byte[] buffer = new byte[Max_Size*2]; |
333 |
byte[] Rcv = new byte[Max_Size + 1]; |
334 |
int bytes, Index, i; |
335 |
Index = 0; |
336 |
while (true) { |
337 |
try { |
338 |
while(Index < Max_Size){ |
339 |
InputStream input = mmSocket.getInputStream(); |
340 |
bytes = input.read(buffer); |
341 |
for(i=0; i<bytes; i++){// 受信バイト数だけ繰り返し |
342 |
Rcv[Index] = buffer[i];// バッファコピー |
343 |
if(Index < Max_Size) |
344 |
Index++;// バイトカウンタ更新 |
345 |
} |
346 |
} |
347 |
Index = 0; |
348 |
mHandler.obtainMessage(BluetoothChat.MESSAGE_READ, Max_Size, -1, Rcv) |
349 |
.sendToTarget(); |
350 |
} catch (IOException e) { |
351 |
Log.e(TAG, "disconnected", e); |
352 |
connectionLost(); |
353 |
BluetoothChatService.this.start(); |
354 |
break; |
355 |
} |
356 |
} |
357 |
} |
358 |
|
359 |
public void write(byte[] buffer) { |
360 |
try { |
361 |
mmOutStream.write(buffer); |
362 |
|
363 |
mHandler.obtainMessage(BluetoothChat.MESSAGE_WRITE, -1, -1, buffer) |
364 |
.sendToTarget(); |
365 |
} catch (IOException e) { |
366 |
Log.e(TAG, "Exception during write", e); |
367 |
} |
368 |
} |
369 |
|
370 |
public void cancel() { |
371 |
try { |
372 |
mmSocket.close(); |
373 |
} catch (IOException e) { |
374 |
Log.e(TAG, "close() of connect socket failed", e); |
375 |
} |
376 |
} |
377 |
} |
378 |
} |
図 12 BluetoothChatService
4. 結果
5. 考察
6. 結言
図 13 パッケージの種類識別[i]
図 14 DC-DCコンバータ参考資料@
図 15 DC-DCコンバーター参考資料A
参考文献
http://www.geocities.jp/zattouka/GarageHouse/micon/MPLAB/12F1822/CPSM/CPSM.htm
http://www.piclist.com/images/www/hobby_elec/pic8_6.htm
http://www.piclist.com/images/www/hobby_elec/pic7_4.htm
小野寺康幸,トランジスタ技術6月号,P160(2010).