390 likes | 585 Views
專題規劃. 指導教授:李博明 組員:4A037030 – 翁睿廷 4A037057 – 何泰慶 4A037068 – 侯建良. 題目 - 機器蟲. 以微電腦控制機械來實現仿生多足蟲,首先用 3D 列印來產生蟲的每個零件,用 Arduino 來控制蟲的前後左右的行動,最後可以用手機藍牙遙控機器蟲的行動. 行程規劃 (Road Map). 2013/12 → 預計專題題目、人力分配 2014/1-2 → 學習專題所需的知識 2014/3-4 → 寫程式,列購買清單
E N D
專題規劃 指導教授:李博明 組員:4A037030 – 翁睿廷 4A037057 – 何泰慶 4A037068 – 侯建良
題目 - 機器蟲 以微電腦控制機械來實現仿生多足蟲,首先用3D列印來產生蟲的每個零件,用Arduino來控制蟲的前後左右的行動,最後可以用手機藍牙遙控機器蟲的行動
行程規劃 (Road Map) • 2013/12 → 預計專題題目、人力分配 • 2014/1-2 →學習專題所需的知識 • 2014/3-4 →寫程式,列購買清單 • 2014/5-6-> 動手完成硬體,並修改程式 • 2014/7-8-> 專題完成 • 2014/9-12 → 參加比賽
arduino學習筆記 1.SoftwareSerial.h SoftwareSerial Library : 用 Arduino任意 2支 I/O Pin 當作 TX 與 RX 腳位來接藍芽模組 用法: SoftwareSerialbluetooth(bluetoothTx, bluetoothRx); 2.EEPROM.h EEPROM Library: 可以利用電壓多次複寫的存儲器,即使斷電也可以保存數據 用法: read : EEPROM.read(address) write : EEPROM.write(address, value)
APP開發學習 需要準備的工具軟體 Java Eclipse Android SDK
手機按鍵開發程序 當建立按鍵時候必須 設定Button的ID 輸入B1 然後再Main的檔案上方打import android.widget.Button; 之後 Button B1; 宣告物件 然後打B1=(Button) this.findViewById(R.id.B1); 對B1的按鍵做連結 最後打B1.setOnClikListener(new Button. OnClikListener(){ Public Void onClick(View arg){ [就可在這裡輸入程式碼對按鍵做動作] }});
arduino馬達控制 影片網址:http://youtu.be/x2WM5SAQrW0
L298N motor 驅動板 正面 背面
驅動板輸入控制 引用網址: http://bugworkshop.blogspot.tw/2013/02/diy-l298n.html
APP 建立SeekBar(刻度)以及設定: 一開始宣告 SeekBar sb1; 之後 在上面打上import android.widget.SeekBar; 然後打sb1=(SeekBar) findViewById(R.id.sb1); 對SeekBar做連結
最後建立SeekBar事件 sb1.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){ @Override public void onProgressChanged(SeekBarseekBar, intprogress,booleanfromUser) { // TODO 自動產生的方法 Stub text3.setText("PWM="+progress); } @Override public void onStartTrackingTouch(SeekBarseekBar) { // TODO 自動產生的方法 Stub } @Override public void onStopTrackingTouch(SeekBarseekBar) { // TODO 自動產生的方法 Stub }}); 此區塊是當progress數值改變時,才會執行內部的指令 此區塊是當手指點下SeekBar時候才會執行內部的指令 此區塊是當手指放開SeekBar時候才會執行內部的指令
ArduinoBluetooth 練習 影片網址:https://www.youtube.com/watch?v=R-NXxovm3cs&feature=youtu.be
程式碼 #include <SoftwareSerial.h> #define RxD 2 #define TxD 3 #define LED 13 unsigned char i; unsigned char Buffer_temp[4]; unsigned char Receive_val; SoftwareSerialblueToothSerial(RxD,TxD); void UART_FUN() { for(i=0;i<5;i++) Buffer_temp[i]=0x0; delay(100);
while(blueToothSerial.available()) { Receive_val=blueToothSerial.read(); Serial.print(Receive_val); Serial.print("\n"); } } void setup() { Serial.begin(9600); blueToothSerial.begin(9600); }
void loop() { UART_FUN(); //上 if(Receive_val==70) digitalWrite(13,HIGH); else digitalWrite(13,LOW); //下 if(Receive_val==66) digitalWrite(12,HIGH); else digitalWrite(12,LOW); //右 if(Receive_val==82) digitalWrite(11,HIGH); else digitalWrite(11,LOW); //左 if(Receive_val==76) digitalWrite(10,HIGH); else digitalWrite(10,LOW); }
遇到問題-APP藍芽設置部分 由於APP藍芽部分尚未完成,所以先從Google play上參考 並學習Bluetooth RCAPP ,一開始不知道這個APP按鍵按 下去會藉由藍芽傳出什麼資料,要寫一個Arduiont程式來讀 目前藍芽是收到什麼資料,觀察收到資料後方可繼續寫程式
3D列印開發流程 3D圖案設計 轉成.stl檔 修復.stl檔(Netfabb) 輸出3D模型 STL(Stereolithography)是一種積層製造(3D列印)專用的格式,能把原本的曲面或實體模型分解成一層一層斷面形狀的數據 Blender可直接轉成輸出.stl檔
Blender模型 與實際尺寸 實際尺寸 w:8.666 x d:19.97 x h:1.75 cm
Arduino車 由於目前尚未購買3D印表機,為了測試程式和觀察實際動作情形, 就以同樣為控制2個馬達的Arduino車來做測試
程式碼 #include <SoftwareSerial.h> #define RxD 2 #define TxD 3 #define LED 13 unsigned char i; unsigned char Buffer_temp[4]; unsigned char Receive_val; SoftwareSerialblueToothSerial(RxD,TxD); constint motorIn1 = 4; constint motorIn2 = 5; constint motorIn3 = 6; constint motorIn4 = 7; void UART_FUN() { for(i=0;i<5;i++) Buffer_temp[i]=0x0; delay(100); while(blueToothSerial.available()) { Receive_val=blueToothSerial.read(); Serial.print(Receive_val); Serial.print("\n"); } }
void setup() { Serial.begin(9600); blueToothSerial.begin(9600); } void loop() { UART_FUN(); //上 if(Receive_val==70) up(); //下 if(Receive_val==66) down(); //右 if(Receive_val==82) right(); //左 if(Receive_val==76) left(); }
void motorstop() { digitalWrite(motorIn1, LOW); digitalWrite(motorIn2, LOW); digitalWrite(motorIn3, LOW); digitalWrite(motorIn4, LOW); } void up() { digitalWrite(motorIn1, HIGH); digitalWrite(motorIn2, LOW); digitalWrite(motorIn3, HIGH); digitalWrite(motorIn4, LOW); } void down() { digitalWrite(motorIn1, LOW); digitalWrite(motorIn2, HIGH); digitalWrite(motorIn3, LOW); digitalWrite(motorIn4, HIGH); } void right() { digitalWrite(motorIn1, HIGH); digitalWrite(motorIn2, LOW); digitalWrite(motorIn3, LOW); digitalWrite(motorIn4, LOW); } void left() { digitalWrite(motorIn1, LOW); digitalWrite(motorIn2, LOW); digitalWrite(motorIn3, HIGH); digitalWrite(motorIn4, LOW); }
本週進度-遙控車+手機藍芽APP 影片網址:https://www.youtube.com/watch?v=sbL9v9FDhhw
Android 程式碼 package edu.stu.cc.amarino.NTL_Bluetooth_Car; import edu.stu.cc.amarino.NTL_Bluetooth_Car.R; import android.app.Activity; import android.content.SharedPreferences; import android.os.Bundle; import android.preference.PreferenceManager; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.widget.SeekBar; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.SeekBar.OnSeekBarChangeListener; import at.abraxas.amarino.Amarino; public class NTL_Bluetooth_Car extends Activity implements OnSeekBarChangeListener { private static final String TAG = "NTL_Bluetooth_Car"; private String DEVICE_ADDRESS = "00:14:03:12:08:44";
final int DELAY = 150; intpower_Val; long lastChange; SeekBarpower_SB; TextViewpowerval_Text; EditTextsetmac_ET; Button up_button,down_button,right_button,left_button; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Amarino.connect(this, DEVICE_ADDRESS); power_SB = (SeekBar) findViewById(R.id.power_seekBar); power_SB.setOnSeekBarChangeListener(this); powerval_Text = (TextView) findViewById(R.id.powerval_LargeText); setmac_ET = (EditText) findViewById(R.id.setmac_EditText); up_button=(Button) this.findViewById(R.id.forward_Button); down_button=(Button) this.findViewById(R.id.back_Button); right_button=(Button) this.findViewById(R.id.right_Button); left_button=(Button) this.findViewById(R.id.left_Button);
up_button.setOnTouchListener(new Button.OnTouchListener(){ @Override public booleanonTouch(View v, MotionEvent event) { // TODO Auto-generated method stub if(event.getAction()==MotionEvent.ACTION_DOWN){ update_Forward(); } else if(event.getAction()==MotionEvent.ACTION_UP){ update_Stop(); } return false; }}); down_button.setOnTouchListener(new Button.OnTouchListener(){ @Override public booleanonTouch(View v, MotionEvent event) { // TODO Auto-generated method stub if(event.getAction()==MotionEvent.ACTION_DOWN){ update_Back(); } else if(event.getAction()==MotionEvent.ACTION_UP){ update_Stop(); } return false; }});
} public void SetMacOnClick() { // 設定MAC按鈕按下之後的動作 Amarino.disconnect(this, DEVICE_ADDRESS); DEVICE_ADDRESS = setmac_ET.toString(); setmac_ET.setHint(DEVICE_ADDRESS); Amarino.connect(this, DEVICE_ADDRESS); } @Override protected void onStart() { super.onStart(); // load last state SharedPreferencesprefs = PreferenceManager.getDefaultSharedPreferences(this); power_Val = prefs.getInt("power_Val", 0); power_SB.setProgress(power_Val); new Thread() { @Override public void run() { try { Thread.sleep(6000); } catch (InterruptedException e) { } Log.d(TAG, "update data"); updateAlldata(); }
}.start(); } @Override protected void onStop() { super.onStop(); PreferenceManager.getDefaultSharedPreferences(this).edit(); Amarino.disconnect(this, DEVICE_ADDRESS); } @Override public void onProgressChanged(SeekBarseekBar, int progress, booleanfromUser) { if (System.currentTimeMillis() - lastChange > DELAY) { updateState(seekBar); lastChange = System.currentTimeMillis(); } } @Override public void onStartTrackingTouch(SeekBarseekBar) { lastChange = System.currentTimeMillis(); }
@Override public void onStopTrackingTouch(SeekBarseekBar) { updateState(seekBar); } private void updateState(final SeekBarseekBar) { switch (seekBar.getId()) { case R.id.power_seekBar: power_Val = seekBar.getProgress(); powerval_Text.setText(Integer.toString(power_Val)); // 將power_Val轉型塞到textbox裡面 update_PowerVal(); break; } update_PowerVal(); } private void updateAlldata() { // 這行用來送出指令到arduino // send state to Arduino // updateRed(); update_PowerVal(); } private void update_PowerVal() { Amarino.sendDataToArduino(this, DEVICE_ADDRESS, 'P', power_Val); }
private void update_Forward() { Amarino.sendDataToArduino(this, DEVICE_ADDRESS, 'F', power_Val); } private void update_Back() { Amarino.sendDataToArduino(this, DEVICE_ADDRESS, 'B', power_Val); } private void update_Left() { Amarino.sendDataToArduino(this, DEVICE_ADDRESS, 'L', power_Val); } private void update_Right() { Amarino.sendDataToArduino(this, DEVICE_ADDRESS, 'R', power_Val); } private void update_Stop() { Amarino.sendDataToArduino(this, DEVICE_ADDRESS, 'S', 0); } }
參考獻文 http://coopermaa2nd.blogspot.tw/2012/06/amarino-android-arduino.html (藍芽連接手機App說明) http://coopermaa2nd.blogspot.tw/2013/01/amarino-with-softwareserial.html (arduino_SoftwareSerial.h說明) http://coopermaa2nd.blogspot.tw/2010/12/arduino-eeprom.html (arduino_EEPROM.h說明)