昨天我們成功控制arduino 輸出 PWM 控制 LED ,今天我們要來嘗試從 arduino 把資料讀回來。
PIN 0 跟 PIN 7 我們都拿來接在可變電阻的 output pin 上,來試看看會發生什麼事吧
直接看 code 吧:
package com.example.test;
import java.io.IOException;
import org.shokai.firmata.ArduinoFirmata;
import org.shokai.firmata.ArduinoFirmataEventHandler;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import com.MyTestLibrary.CountingSensorUpateRate;
public class MainActivity extends ActionBarActivity{
private boolean timerHasStarted = false ;
private boolean ArduinoBlink = false ;
private Button startB;
private TestCounting CountDownTimer;
private TextView AccelX;
private TextView AccelY;
private TextView AccelZ;
private TextView OrienX;
private TextView OrienY;
private TextView OrienZ;
private SensorActivity MySensor;
private TextView TimeView;
private TextView ElapsedView;
private TextView CountAccel,CountOrien;
private TextView seekBarValue,Variable_resistor,Variable_resistor2;
private long timeElapsed;
private long startTime = 60*1000;
private long interval = 1*100; // 0.1 sec. per time interval
private CountingSensorUpateRate MyCountingSensorUpdateRate;
private SeekBar PWMValue;
private Handler handler;
private ArduinoFirmata arduino;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startB = (Button) this.findViewById(R.id.button1);
startB.setOnClickListener(new Button_Listener(this));
AccelX = (TextView) this.findViewById(R.id.AccelX);
AccelY = (TextView) this.findViewById(R.id.AccelY);
AccelZ = (TextView) this.findViewById(R.id.AccelZ);
OrienX = (TextView) this.findViewById(R.id.OrienX);
OrienY = (TextView) this.findViewById(R.id.OrienY);
OrienZ = (TextView) this.findViewById(R.id.OrienZ);
TimeView= (TextView) this.findViewById(R.id.timer);
ElapsedView= (TextView) this.findViewById(R.id.timeElapsed);
CountAccel = (TextView) this.findViewById(R.id.UpateRate_Accel);
CountOrien = (TextView) this.findViewById(R.id.UpateRate_Orien);
seekBarValue = (TextView) this.findViewById(R.id.seekBarValue);
Variable_resistor = (TextView) this.findViewById(R.id.Variable_resistor);
Variable_resistor2 = (TextView) this.findViewById(R.id.Variable_resistor2);
PWMValue = (SeekBar) this.findViewById(R.id.seekBar1);
handler = new Handler();
CountDownTimer = new TestCounting (startTime,interval);
MyCountingSensorUpdateRate = new CountingSensorUpateRate();
MySensor = new SensorActivity();
MySensor.onPause();
this.arduino = new ArduinoFirmata(this);
final ActionBarActivity self = this; // 下面這段是今天新增的,主要是設定 arduino firmata 物件發生錯誤時/中斷連線是該怎做
arduino.setEventHandler(new ArduinoFirmataEventHandler() {
public void onError(String errorMessage) {
}
public void onClose() {
self.finish(); // 直接關閉 APP
}
});
PWMValue.setOnSeekBarChangeListener( new OnSeekBarChangeListener() {
int progressValue = 0;
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
progressValue = progress;
seekBarValue.setText(String.valueOf(progressValue));
if(arduino.isOpen()){
arduino.analogWrite(11, progressValue); // pinNumber, value(0~255)
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
//seekBarValue.setText(String.valueOf(progressValue));
}
});
// 建立 一個 THREAD 來讀arduino 資料
Thread thread = new Thread(new Runnable() {
public void run() {
while (arduino.isOpen()) {
try {
Thread.sleep(100);
handler.post(new Runnable() {
public void run() {
int analog_value = arduino.analogRead(0); // 要求讀回 PIN 0 的資料
boolean digital_value = arduino.digitalRead(7); // 要求讀回 PIN 7 的資料
Variable_resistor.setText("analogRead(0) = "+ String.valueOf(analog_value));
Variable_resistor2.setText("digitalRead(7) = "+ String.valueOf(digital_value));
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
// 我們改為啟動 APP 時就自動嘗試連線 arduino , 如果找不到 arduino 就關閉 app
try {
arduino.connect();
arduino.pinMode(7, ArduinoFirmata.INPUT); // 設定這兩個 PIN 為 input mode
arduino.pinMode(0, ArduinoFirmata.INPUT);
thread.start();
} catch (IOException e) {
e.printStackTrace();
finish();
} catch (InterruptedException e) {
e.printStackTrace();
finish();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.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();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
class Button_Listener implements OnClickListener {
public Button_Listener(MainActivity activity) {
}
@Override
public void onClick(View view) {
if (!timerHasStarted) {
CountDownTimer.start();
MySensor.onResume();
timerHasStarted = true;
startB.setText("RESET ME!");
} else {
CountDownTimer.cancel();
MySensor.onPause();
timerHasStarted = false;
startB.setText("Start Counting... 60 Sec.");
// arduino.close();
}
}
}
public class TestCounting extends CountDownTimer{
int Count = 0;
public TestCounting(long startTime, long interval) {
super(startTime, interval);
}
@Override
public void onFinish(){
TimeView.setText("Time's Up");
ElapsedView.setText("Time Elapsed:" + String.valueOf(startTime));
CountAccel.setText("Upate Accel "+ MyCountingSensorUpdateRate.GetCounting("TYPE_ACCELEROMETER") +" Times per "+startTime+" ms");
CountOrien.setText("Upate Orien "+ MyCountingSensorUpdateRate.GetCounting("TYPE_ORIENTATION") +" Times per "+startTime+" ms");
MyCountingSensorUpdateRate.Clear();
MySensor.onPause();
}
@Override
public void onTick(long millisUntillFinished){
TimeView.setText("Time remain : "+ millisUntillFinished);
timeElapsed = startTime - millisUntillFinished;
ElapsedView.setText("Time Elapsed : " + String.valueOf(timeElapsed));
if(Count%10==1){
arduino.digitalWrite(13, ArduinoBlink); // on board LED
ArduinoBlink = ! ArduinoBlink;
}
Count++;
}
}
/* 下略 Sensor 部分*/
}
看起來是不是很容易呢?
主要就是 analogRead 以及 digitalRead 這兩個method,
但是! 人生中的『但是』常常給我們驚喜無窮 !
這樣寫是讀不出資料的,編譯 / 安裝 / 測試 都不會發生 crash 跟跳 error , 沒資料就是沒資料,彷彿 arduino input 被蓋上國防布一般...
筆者我針對這兩個method 曾奮鬥了 4 個鐘頭還是一頭霧水 XD
先賣個關子,下回再一步一步解決這個奇怪的問題
我們明天見