テキスト受信
次はArduinoからAndroidへテキストを送信します。
Arduino側の設定
回路は前回と同様なので、スケッチのみ変更します。
Arduino UNO
#include <SoftwareSerial.h>
//androidで使用するピンを指定
SoftwareSerial android(2,3);
void setup(){
//android用のシリアルのポートを設定
android.begin(9600);
// arduinoのシリアルモニタ用
Serial.begin(19200);
Serial.write("init");
}
void loop(){
if(android.available()){
Serial.write(android.read());
}
if(Serial.available()){
android.write(Serial.read());
}
}
Arduino Mega
void setup(){
//android用のシリアルのポートを設定
Serial1.begin(9600);
// arduinoのシリアルモニタ用
Serial.begin(19200);
Serial.write("init");
}
void loop(){
if(Serial1.available()){
Serial.write(Serial1.read());
}
if(Serial.available()){
Serial1.write(Serial.read());
}
}
Android側の設定
以下のそれぞれのファイルに青の箇所を追加してください。
なお、xmlを変更後に保存していない状態では、MainActivity.javaのエラーが消えませんのでご注意ください。
MainActivity.java
package gclue.com.myusbhost;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.hardware.usb.UsbManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.ftdi.j2xx.D2xxManager;
import com.ftdi.j2xx.FT_Device;
public class MainActivity extends ActionBarActivity {
private FT_Device ftDev = null;
private static Context mContext;
private D2xxManager ftdid2xx;
private static final String TAG = "USB";
private boolean isReading = false;
private ReadThread mReadThread;
private int iavailable = 0;
private static final int readLength = 512;
byte[] readData;
char[] readDataToText;
private TextView mInputValue;
private Button mOutputButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
ftdid2xx = D2xxManager.getInstance(this);
} catch (D2xxManager.D2xxException ex) {
Log.e(TAG,ex.toString());
}
mContext = this.getBaseContext();
openUsb();
mInputValue = (TextView)findViewById(R.id.inputValue);
// ボタンが押されたらUSBに値を送り込む
mOutputButton = (Button)findViewById(R.id.outputButton);
mOutputButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SendMessage("1");
}
});
}
public void openUsb(){
int devCount = 0;
devCount = ftdid2xx.createDeviceInfoList(this);
if (devCount <= 0)
{
Toast.makeText(this, "デバイスが発見できません。" + Integer.toString(devCount), Toast.LENGTH_LONG).show();
Log.i(TAG,"デバイスが発見できましせんでした。");
return;
}
else{
Toast.makeText(this, "" + devCount + "個のデバイスを発見しました。", Toast.LENGTH_LONG).show();
Log.i(TAG,"" + devCount + "個のデバイスを発見しました。");
}
if(null == ftDev)
{
ftDev = ftdid2xx.openByIndex(mContext, 0);
}
else
{
synchronized(ftDev)
{
ftDev = ftdid2xx.openByIndex(mContext, 0);
}
}
//ftDev.setBitMode((byte) 0, D2xxManager.FT_BITMODE_RESET);
ftDev.setBaudRate(9600);
ftDev.setDataCharacteristics(D2xxManager.FT_DATA_BITS_8, D2xxManager.FT_STOP_BITS_1, D2xxManager.FT_PARITY_NONE);
ftDev.setFlowControl(D2xxManager.FT_FLOW_NONE, (byte) 0x0b, (byte) 0x0d);
ftDev.purge((byte) (D2xxManager.FT_PURGE_TX | D2xxManager.FT_PURGE_RX));
ftDev.restartInTask();
readData = new byte[readLength];
readDataToText = new char[readLength];
mReadThread = new ReadThread(mHandler);
mReadThread.start();
isReading = true;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void SendMessage(String msg) {
if(ftDev == null){
return;
}
synchronized (ftDev) {
if (ftDev.isOpen() == false) {
Log.e("j2xx", "SendMessage: device not open");
return;
}
ftDev.setLatencyTimer((byte) 16);
if (msg != null) {
byte[] OutData = msg.getBytes();
ftDev.write(OutData, msg.length());
}
}
}
private class ReadThread extends Thread
{
Handler mHandler;
ReadThread(Handler h){
mHandler = h;
this.setPriority(Thread.MIN_PRIORITY);
}
@Override
public void run()
{
int i;
while(true == isReading)
{
try {
Thread.sleep(50);
} catch (InterruptedException e) {
}
synchronized(ftDev)
{
iavailable = ftDev.getQueueStatus();
if (iavailable > 0) {
if(iavailable > readLength){
iavailable = readLength;
}
ftDev.read(readData, iavailable);
String mData = new String(readData);
Message msg = mHandler.obtainMessage();
msg.obj = mData;
mHandler.sendMessage(msg);
}
}
}
}
}
/**
* 描画処理はHandlerでおこなう
*/
Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
String mData = (String)msg.obj;
mInputValue.setText(mData);
}
};
BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
// never come here(when attached, go to onNewIntent)
openUsb();
} else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
if(ftDev != null) {
ftDev.close();
isReading = false;
}
}
}
};
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/inputValue"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<Button android:id="@+id/outputButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
android:layout_gravity="center_horizontal" />
</LinearLayout>
PCとAndroid端末を接続してプログラム実行し、Android端末側に実行ファイルを作成します。
前回と同様に、Arduino側はシリアルモニタを表示した状態で待機します。
PCとArduino、ArduinoからAndroid端末にそれぞれコードで接続します。 接続ができましたら、Android端末のアプリ一覧より、今回作成した「UsbHostPrint」を実行します。
起動しましたら画面上部にあります「Button」を押下します。
Android側のアプリにて初期表示されている「init」の後ろに、「1」が「Button」を押した回数分出力されました。
次にArduinoのInput部分に値をいれて、送信ボタンを押下します。
スマートフォンのアプリ画面の左上に、Arduinoから送信した文字が出力されます。