Category Archives: Android

[課程紀錄]Arduino+手機App 物聯網應用實作:打造環境感測裝置@T客邦

作者/攝影 曾吉弘
課程時間  2017 2/11
課程講師 曾吉弘、薛皓云
課程場地  T客邦創客基地

2/11 星期六寒風颼颼呢,但在T客邦創客基地有20位學員一起來打基礎,Arduino 與 Android 的藍牙通訊。現場學員來自各方,有來自基隆的國小老師,也有電子公司工程師,也有純粹想學的朋友們。

同學們的問題相當五花八門,差點就被問倒了,但這正是教學相長的開始,您說是嗎?

本日課程主軸是告訴您Arduino(介面與網路功能較缺乏) 與 Android 手機(採用App Inventor 編寫程式)兩者結合之後有哪些有趣的應用

  • 手機可以做為顯示器來呈現Arduino丟過來的感測器資料(手機應該沒辦法讓您直接接感測器或LED吧,但您想的到的基礎電子元件,Arduino幾乎都可以存取)
  • 或是控制器根據某些條件(簡訊、Email、或是opendata 查詢結果) 來觸發Arduino 執行某些動作。

兩天課表的 Google doc 在這邊,請和我們一起學習吧,您可以根據文末的投影片或到CAVEDU技術部落格查詢[雙A],會有相當豐富的資料。

自誇一下,[Arduino從入門到雲端]這本書現場詢問度很高喔

 

以下是上課照片

上課時我都會用123D Circuit來介紹,除了可以用投影機以外(大家想想看要學生走過來走過去看麵包板的接線…),還可以模擬,接錯線不小心燒掉元件的機會可以降低一點。我在很多學校都直接要求用這個交作業呢。

當天助教(其實我們的助教都是講師)薛老師,本著對於初音的熱愛開始玩Arduino、Unity等許多奇奇怪怪的應用。有什麼冷門的疑難雜症問他就對了~

通訊之夜投影片:


 

相關文章:

[雙A計劃]自己的拳擊機器人自己改裝_使用Arduino;AppInventor by TKUEE-CILAB

robot13

今天小編要跟各位分享一個機器人改裝教學,它源自淡江大學電機系-CILAB實驗室的專題作品,

這項改裝作品在Tokyo Maker Fairer發表後,販賣這個機器人的公司也將這個發想概念運用在他們新的機器人產品上,

讓人覺得Maker與商品製造其實能很好的相輔相成。話不多說,我們來看看這個機器人影片吧。

看了這個影片,也想要自己動手改裝的話,請繼續往下看喔

  • 本項作品使用日本TOMY公司生產的“BATTROBORG 4G”拳擊機器人玩具,
  • 將原本的體感操控,改造成能利用Android裝置,透過藍芽來控制機器人的動作(體感下一篇敬請期待)。

一組機器人需要準備

  • Arduino開發版*1
  • 藍芽模組*1
  • 3號*4電池盒*1
  • 光耦合器元件PC817*2

電路測試

  • 請先按照附圖之電路圖在麵包板上佈置電路

在此我們利用LED來測試我們在光電耦合器的使用上是否正確

。若是配置正確,在我們用手機向藍芽裝置傳送資訊時,對應的LED就會閃碩。

robot01

Arduino程式編輯

在此我們監聽接上藍芽模組後的TxRx,當藍芽接收到傳送的字元‘0’或‘1’時,分別啟動連接於Pin 10&11的光電耦合器,藉此讓連接於耦合器另一端的LED的正負極導通。

int input = 0,left=10,right=11;

void setup(){

  pinMode(left,OUTPUT);  
  pinMode(right,OUTPUT);  

  Serial.begin(9600);

}

void loop(){

  while (Serial.available()>0){

    input= Serial.read();
    Serial.println(input);

    if(input=='0'){

      digitalWrite(left,HIGH);
      delay(100);
      digitalWrite(left,LOW);

    }else if(input=='1'){

      digitalWrite(right,HIGH);
      delay(100);
      digitalWrite(right,LOW);

    }

  }

}

AppInventor撰寫App

  • 1 介面初始化
    • 我們在APP介面(圖1a)上配屬了三個按鈕(上方的左拳&右拳與右下方的藍芽裝置斷線),與一個用來列出並選取可連線的藍芽裝置的ListPicker(左下藍芽裝置連線)。因為本APP需要與藍牙裝至連線,所以要將BluetoothClient元件加入至介面中。在程式初始化後,因為還沒連上任何藍芽裝置的關係,這時除了BTConnect外的其他按鈕將呈現灰色無法選取的狀態(圖1b)。

robot02

圖1a

robot03

圖1b

2 藍芽裝置連線

  • 在我們開啟藍芽裝置選單前,要先將可供連線的裝置清單輸入至選單中(圖2a)。選取裝置並確定連線成功後,將原本設為不可選取的左拳、右拳以及裝置斷線按鈕開啟(圖2b)。

robot04

圖2a

robot05

圖2b

3 藍芽功能實作

  • 當我們與裝置連線後,點擊左拳或右拳按鈕時,會透過藍芽對連線裝置送出字元的1與0資料(圖3a)。按下裝置斷線的按鈕時,則會與裝置斷開連結,並重新將需使用到藍芽功能的按鈕關閉(圖3b)。

robot06

圖3a

robot07

圖3b

實際測試

  • 將撰寫完成的APP燒錄至手機,當我們與Arduino上的藍芽模組連結,並按下左拳與右拳按鈕時,與之對應的LED就會閃碩,代表我們光電耦合器的使用與設置是正確的。

機器人手把

  • 手把與基板拆解
    • 本作品使用的拳擊機器人玩具為日本TOMY公司生產的“BATTROBORG 4G”,同樣方法適用於同公司前代產品“BATTROBORG 20“。

將手把拆開後,可以看到控制器是利用搖晃時,撞針撞擊簧片,簧片互相接觸後導致線路導通,觸發一個揮拳的訊號,因此我們才在此作品上使用光耦合器來當作觸發開關(圖4)。

robot08

圖4,橘線標記處為撞針與簧片

 

將基板拆下,如下圖(圖5),可以看到三個部分分別為基板供電、右拳揮拳以及左拳揮拳,這些就是等下要跳線到麵包板上使用的接點。(在這裡可以選擇將原廠焊好的線留著繼續使用,或者自行換上單芯線)

robot09

圖5,橘線標記處分別為 a.基板供電 b.右拳揮拳 c.左拳揮拳

成品測試

  • 按照下圖(圖6)指示將基板的左右揮拳腳位跳線至對應的光耦合器(因訊號觸發機制為腳位導通,故接線無正負之分),並將基板電源供電腳位分別接上+5V和接地,Arduino接電,及可讓基板與機器人連線,並讓手機透過藍芽操控拳擊機器人。

robot10

圖6

Maker Faire Tokyo展示的照片

robot11 robot12

淡江城區部Android職訓課程,18堂=4.5月,結訓囉!

大家…   辛苦了。從三月開訓到今天,一共18周共54個小時,一起走過 Android UI設計、觸碰與手勢、感測器、2D3D繪圖、網路(Wifi/藍牙)、樂高機器人、Google Map、Facebook、Google API(AdSense、Picasa與Youtube等)、資料儲存等課題。

機器人與Processing 是很有趣的課程,也算是阿吉老師的特色(雜七雜八)吧。與其在課堂上一直帶程式碼,我覺得告訴同學有哪些可能性正在發生更重要。所以有同學也跑去 FabCafe 喝過咖啡了,也有來 Maker Faire 找老師聊天,或是帶家裡的小朋友去參加 MakerBar 的活動。有時候無目的亂晃亂看,說不定會有意想不到的收穫呢。

也感謝大家在工作繁忙之餘,都還是有作回家作業,真感動。我對同學的期許(其實很多是業界資深前輩)就是:結訓的時候比自己進來的時候厲害,這樣就好了。每個人經歷與背景都不一樣,不需要和別人比。

今天是大家專案demo的日子,是不是有點緊張呢?來看看一些有趣的專題吧

IMG_2262 - 複製

拖吊資訊查詢,這是 SQlite 的畫面,Android app 藉此來查各拖吊場的資訊並取出各個欄位,可以打電話給拖吊場、定位與叫計程車等等,一氣呵成QQ…

2014-07-09 19.36.18

2014-07-09 19.30.41

電視節目查詢。可以查詢民視的節目,還可以查詢經典台詞:9527 之類的

2014-07-09 20.02.38

小強!小強你怎麼了小強!周星馳系列真是華人經典

2014-07-09 20.03.57

藍牙遙控 LED燈條。手機發送訊號給,這位大哥本身硬體底子不錯,使用12V的電源,並用 TI 的晶片來控制 LED 的顏色、多種閃爍模式與呼吸燈效果。

2014-07-09 20.31.29

實際demo的效果非常好喔!請看影片

[youtube=http://youtu.be/ORCovzOklY0]

2014-07-09 20.31.15

爸爸寫給孩子的英文生字小遊戲,真是好爸爸啊

2014-07-09 20.57.02

會出現題目(南瓜),要在時限之內點選正確的英文字母,有趣的是點了某個字母之後,字母會消失然後樓上的字母會掉下來,很像Candy Crush喔。最下面的題號、答對答錯數目以及得分也都做出來了。

2014-07-09 20.58.16

[Android 結合 Google Chart API] 機器人原地轉一圈產生雷達圖

機器人原地轉一圈之後,將超音波感測器值透過藍牙送給Android 手機,再呼叫 Google Chart API 雲端圖表功能來取得雷達圖。可以畫出非常精美的圖表。重點在於靈活應用 Google Chart API  的語法就可以囉!

直接點選以下連結就可以看到雷達圖,詳細參數設定請參閱 Google Chart API 官網或以下延伸閱讀

https://chart.googleapis.com/chart?cht=r&chs=320×320&chxt=x&chxl=0:|0|45|90|135|180|225|270|315&chd=t:60,40,30,100,76,99,22,57,80

本範例是結合樂高機器人的超音波感測器來達到簡易地圖掃描的效果,歡迎試試看。以下範例是2014年淡江大學智慧型行動裝置整合機器人控制課程的作業之一。感謝電機系周煜同學(已畢業)做出相當好的版本呢。

 

12345

[youtube=http://www.youtube.com/watch?v=DBvhrxkb24M]

延伸閱讀:

Google Chart API 教學

Google Chart 隨機產生折線圖

淡江電機 Android 機器人整合課程網站

140523淡江電機 Android 行動裝置整合機器人控制課程,期末專題展示

Code Android端

package com.example.nxtsense;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Set;
import java.util.UUID;



import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import android.os.Build;

public class MainActivity extends ActionBarActivity {
	private BluetoothAdapter adapter;
	private BluetoothSocket nxtSocket;
	public DataInputStream nxtDataIn;
	public DataOutputStream nxtDataOut;
    public final int MODE_CONNECT_NXT = 0, MODE_CONTROL = 1;
    private int mode;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fragment_main);
        adapter = BluetoothAdapter.getDefaultAdapter();
    	if(adapter==null)
        {
        	Toast.makeText(this, "No Bluetooth adapter found", Toast.LENGTH_SHORT).show();
        	this.finish();
        }
    	if(!adapter.isEnabled())
			startActivityForResult(new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE), 1);
    	
    	try {
			setMode(MODE_CONNECT_NXT);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	
    	Button getvalue=(Button)findViewById(R.id.get);
    	getvalue.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				try {
					CommandNXT();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}
		});
        
    }

    public void CommandNXT() throws IOException{
    	String y="";
    		nxtDataOut.writeInt(1);
    		nxtDataOut.flush();
    	
    	//	int x=nxtDataIn.readInt();
    		y=String.valueOf(nxtDataIn.readInt())+","
    				+String.valueOf(nxtDataIn.readInt())+","
    				+String.valueOf(nxtDataIn.readInt())+","
    				+String.valueOf(nxtDataIn.readInt())+","
    				+String.valueOf(nxtDataIn.readInt())+","
    				+String.valueOf(nxtDataIn.readInt())+","
    				+String.valueOf(nxtDataIn.readInt());
    	
					//TextView tv=(TextView)findViewById(R.id.value);
			    	//tv.setText(String.valueOf(x));
		
    	String myURL =" https://chart.googleapis.com/chart?cht=r&chs=320x320&chxt=x&chxl=0:|0|45|90|135|180|225|270|315&chd=t:"+y;         
        WebView myBrowser=(WebView)findViewById(R.id.mybrowser);  
  
        WebSettings websettings = myBrowser.getSettings();   
        websettings.setJavaScriptEnabled(true);  
         
        myBrowser.setWebViewClient(new WebViewClient());  
  
        myBrowser.loadUrl(myURL);  	
    	
    	
    	
    }
    public void setMode(int _mode) throws IOException
    {
    	Button connect=(Button)findViewById(R.id.buttonConnect);
    	mode = _mode;
    	if(mode==MODE_CONNECT_NXT)
    	{
    		
    		connect.setOnClickListener(new Button.OnClickListener() {
    			public void onClick(View arg0) {
    				connectNxt();
    				}
            });
    	}
    	
    	else if(mode==MODE_CONTROL)
    	{
    		connect.setEnabled(false);
    	}
    	else 
    		throw new IllegalArgumentException();
    }
    
    private void connectNxt()
    {
    	if(mode!=MODE_CONNECT_NXT) //檢查模式
    		throw new IllegalArgumentException();
    	
    	String name;
    	BluetoothDevice nxt = null;
    	
    	if((name = ((EditText) findViewById(R.id.editNxtName)).getText().toString()).equals("")) //檢查是否為空字串
    	{
    		Toast.makeText(this, "Please provide the name of your NXT", Toast.LENGTH_SHORT).show();
    		return;
    	}
    	
        Set<BluetoothDevice> devicesSet = adapter.getBondedDevices(); //取得裝置清單
        
        if(devicesSet.size()==0) //找不到裝置
        {
        	Toast.makeText(this, "No devices found", Toast.LENGTH_SHORT).show();
        	return;
        }
        
        for (BluetoothDevice device : devicesSet) //搜尋裝置
        {
            if (device.getName().equals(name))
            {
            	nxt = device;
                break;
            }
        }
        
        if(nxt==null) //找不到裝置
        {
        	Toast.makeText(this, "NXT not found", Toast.LENGTH_SHORT).show();
        	return;
        }
        
        try
        {
        	//建立nxt socket
			nxtSocket = nxt.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
			nxtSocket.connect();
			nxtDataOut = new DataOutputStream(nxtSocket.getOutputStream());
			nxtDataIn = new DataInputStream(nxtSocket.getInputStream());
		}
        catch(IOException e)
		{
        	Toast.makeText(this, "Connection failure", Toast.LENGTH_SHORT).show();
        	return;
		}

    	Toast.makeText(this, "Connected", Toast.LENGTH_SHORT).show();
		try {
			setMode(MODE_CONTROL);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }




   

}
Code. Android receive ultrasonic value from Lego robot

Code 機器人端使用 leJOS

import lejos.nxt.*;
import lejos.nxt.comm.*;
import lejos.util.Delay;

import java.io.*;
public class motor_control{
	public static void main(String args[]) throws IOException{
		Button.ESCAPE.addButtonListener(new ButtonListener(){
				public void buttonPressed(Button b){
					System.exit(0);
					}
				public void buttonReleased(Button b){
					
				}
		});
		System.out.println("Waiting");
		BTConnection btc = Bluetooth.waitForConnection(0, NXTConnection.RAW);
		DataInputStream dis = btc.openDataInputStream();
		DataOutputStream dos = btc.openDataOutputStream();
		System.out.println("Connected");
		UltrasonicSensor ultrasonic1 = new UltrasonicSensor(SensorPort.S2);
		int Ultrasonicvalue1;
		while(true){
			int a=dis.readInt();
			if(a==1){
				for(int i=0;i<7;i++){
					Motor.A.setSpeed(100);
					Motor.B.setSpeed(100);
					Motor.A.backward();
					Motor.B.forward();
					Delay.msDelay(822);
					Ultrasonicvalue1=ultrasonic1.getDistance();
		//	System.out.println(Ultrasonicvalue1);
			
				try {
					dos.writeInt(Ultrasonicvalue1);
					dos.flush();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			
			}
				Motor.A.setSpeed(0);
				Motor.B.setSpeed(0);
				Motor.A.backward();
				Motor.B.backward();
			}
		}
			}
}
Code. Robot send out ultrasonic value to Android (leJOS)

140523淡江電機 Android 行動裝置整合機器人控制課程,期末專題展示

今天是阿吉老師淡江電機智慧型行動裝置整合機器人控制課的最後一堂課,也是我們課程的期末專題發表。主要的內容是於 Eclipse IDE 中使用 Java程式語言來開發各種機器人控制專題。

主題有保全機器人、路面避障機器人、發射機器人、生活便利機器人、繪圖機器人、堆高機、分類機器人、測速照相機器人、搬運機器人、搖擺彈彈球、搬運機器人、大嘴鱷魚、全景拍照機器人等等。而從期中到期末的課程這段期間,老師教了更多更難的google API跟Facebook程式碼。還記得Facebook程式碼那堂課大家驚呼連連。原來打了幾行指令之後就可以看到那個人所打過卡的所有地方等等的訊息,難怪大家都說Facebook對於個人資料並沒有做很好的隱私。

不過還是建議大家不要把太多隱私的東西放在網路上喔!上次期中報告的時候,大家都只完成了一些進度,希望在期末的時候大家都能夠有更多進步空間。

 

教學網站請按我 <- 投影片與code 學生專題都在這邊下載喔!!

 

阿吉老師今天穿的很正式,想必是對同學的期末報告非常的重視。

IMG_0278

這組同學報告的是倉儲搬運機器人

IMG_0267

還有指定地點送物品的機器人

IMG_0288

IMG_0287

全景拍照機器人,不過拍照功能必須要手按才能。

IMG_0313

IMG_0317

圈圈叉叉遊戲機器人,還蠻有創意的一組報告,可以跟人互動玩遊戲。

IMG_0319

IMG_0320

鈴鐺分類機器人,但是因為鈴噹的表面太過反光,導致機器人在判讀的時候總是錯誤。

希望同學可以將鈴鐺加工之後Demo會表現更好喔!!

IMG_0327

IMG_0335

街機遊戲機器人,構想很棒。但是並沒有做出遊戲該有的介面。

如果有把平常玩遊戲介面的那種計分、秒數、路徑都顯示在手機上會更完整喔!

IMG_0367

大嘴鱷魚,是小編覺得最棒的一組專題。跟其中比起來多了更多功能,還有背景音樂。

而且Demo的時候讓全班的同學都圍了過來,被嚇人的機器人逗得笑聲連連。

IMG_0383IMG_0390

偵測機器人,可以手機遙控機器人進入災區探查。這組同學對於程式碼的部分非常認真。報告的時候還分享自己遇到的Bug以及解決辦法。

IMG_0399

IMG_0404

自動平衡橋機器人,到了某個快掉下去的角度就會使橋面歸正。

IMG_0415

IMG_0424

測速機器人,不過這組的同學可能一開始的構想沒有查好測速的原理。導致期末的時候誤解了測速的意思。

IMG_0481

課程結束之後不免俗地要來一個大合照,感謝老師這學期的教導喔!

IMG_0496

【機器人機構近拍】

操控抓取機器人

IMG_0501

測速機器人

IMG_0503

全景拍照機器人

IMG_0504

鈴鐺分類機器人

IMG_0505

勘查機器人

IMG_0507

平衡橋機器人

IMG_0508

 

140521 海洋大學Arduino微處理機課程 Android遙控Arduino機器人

不管怎麼說, 遙控機器人最好玩. 在連續一個月都比較偏靜態的專題之後, 今天要用 App Inventor  來寫按鈕控制程式來控制 Arduino 機器人. 我們之後會在雙A計畫系列教學文中來介紹如何做出這樣功能的互動機器人專題

您可以從先前的文章中找到上課的內容。請參閱[海洋大學機械系 Arduino 微處理機教學網站]

[youtube=http://youtu.be/xeLjGcejtsQ]

2014-05-20 19.49.20

另外也有同學用 Wii 手把來控制機器人, 雖然只是用搖桿(概念就是兩個可變電阻), 但還是很吸睛哩

2014-05-20 19.22.51

Android Google Map API – Eclipse 環境建置

本篇是幫大家整理出在 Eclipse 中建置 Android Google Map API V2 環境時,可能會遇到的種種狀況。說真的狀況真的很多, 不知道 Google 為什麼要改得這麼複雜, code 本身不是問題, 環境才是問題.

本文件整理自 Google Map Android API V2 教學頁面 。投影片可直接下載,也請點這裡下載 source code (HelloMap.rar)。基本上來說就是以下幾個步驟:

  1. 安裝 Google Play services SDK
  2. 在本機取得SHA1 憑證
  3. 到Google APIs Console 網站申請API key
  4. 新增專案、設定權限
  5. 加入地圖

在除錯過程時,也幫大家準備了一些溫馨小提醒,這些也都寫在投影片中了。

  1. 如果程式一執行就閃退,那八成是 API Key 有問題,請檢查或乾脆重新申請一個 key。
  2. 如果程式可以執行但是沒有畫面(白底), 請檢查是否有新增 INTERNET 的 uses-permission 以及您的手機是否可以上網。
  3. 換不同的電腦來開發,就要重新申請一個 key (因為 SHA1 不同).
  4. 確認認使用 debug.keystore 來產生 SHA1
  5. 記得在 AndroidManifest.xml 中加入 API Key 、meta data與相關權限
  6. 如果使用別人的範例來修改時,請記得更改 package name。因為 API Key 是用 SHA1 + 自訂的package name 去申請所以一定不一樣。 
  7. 有無匯入 Google Play services libraries

請注意的是由於模擬器上沒有 Google Play,所以無法執行在模擬器上。以下畫面都是執行在實體手機上截圖。網路上有教您如何在模擬器上安裝 Google Play,但我覺得還是直接裝在手機上比較乾脆…

投影片我們上傳到 Slideshare 了, 請點選以下投影片就可以下載.


下圖是範例程式執行的畫面

2014-05-07 05.31.33

 

也請參考由南開科大老師所維護的 [智慧生活科技專業社群] 中的 Google Map 教學,有一個點兩下呼叫 Google Map 規劃路徑的範例,非常方便。

2014-05-07 07.07.24

 

 

140418 淡江電機 Android 行動裝置整合機器人控制課程,期中專題展示

今天阿吉老師到淡江大學上課,而今天的課程是期中的專題展示,主要的內容是於 Eclipse IDE 中使用 Java程式語言來開發各種機器人控制專題。

這次的主題有保全機器人、路面避障機器人、發射機器人、生活便利機器人、繪圖機器人、堆高機、分類機器人、測速照相機器人、搬運機器人、搖擺彈彈球、搬運機器人、大嘴鱷魚、全景拍照機器人等等。

既然是Android,同學們就要思考Android手機資源要如何與機器人整合,而不是換個程式語言玩碰碰車而已。手機上的動作感測器、GPS、照相機、網路連線、麥克風等等,對機器人來說都是很關鍵的功能啊!

另一方面,各種 Google API例如 Google Map、Google Chart、Google Application Engine 或是較簡單的語音輸入/輸出等,都能讓機器人更豐富。

來看看CAVEDU之前做的 Google Map 結合機器人的概念影片以及 openCV / Android 實作,讓機器人可以透過手機的影像辨識結果來移動。

[youtube=https://www.youtube.com/watch?v=qvI04snZRuU] [youtube=https://www.youtube.com/watch?v=k6Lelf7SNWI]

軟滑小編也有修這堂課喔!會修這堂課是因為,之前大三有修過 leJOS 樂高機器人的課程。想說要更進一步的學更多相關的課程才修的。不過本學期的課程內容比起以往難度提高很多很多,許多同學都為了把專題做的更好,準備了很久。

寫app的方式有很多種,相較起來App Inventer,java的變化更多更複雜,也代表著程式碼更多更難。所以App Inventer真的是很適合學習Android入門的程式語言喔!但換個角度來說,如果要做到更完整的功能,還是要回到 Android 正規開發環境哩,真難抉擇啊

同學們都很認真的上台報告

這組的目標是藉由手機的姿態感測器讓機器人保持在翹翹板中央,做到簡易的動態平衡控制。

來看一下同學們的作品有哪些,有些的機構設計的很不錯!

分類機器人
分類機器人Demo
大嘴鱷魚
全景拍照機器人
推高機

最後由老師講評整個專題展示結果,大家的表現… 還有很大的進步空間啦,希望學期末報告的時候都可以更棒!

阿吉老師講評

閱讀延伸

AppInventor – 圖形化Android

Android相關文章

精簡版Android環境建置

螢幕快照 2014-02-20 下午10.44.45

https://sites.google.com/a/cavedu.com/androidrobot2014/setup

1. 下載並安裝 Java Developer Kit  

2. 下載並安裝 ADT-Bundle
    下載完成之後解壓縮,開啓Eclispe即可。
    注意:這只會包含最新的Android版本。其餘版本需自行下載(非必要)
畫面跑掉怎麼辦?
工具列 Window-> Reset Perspective
檢查Android SDK路徑
工具列 Preferences->找到Android選項。右側的 SDK Location
重要介面
SDK Manager(在此管理所有Android版本與相依套件)
AVD Manager(在此管理所有模擬器)
AVD是指 Android Virtual Machine,就是手機模擬器。當沒有實體手機時,可用模擬器來執行(部分應體功能會無法使用)
新增模擬器
1. 點選New…
2. 設定AVD Name, Device(解析度,不用選太高,電腦會變慢), Target(Android版本)。設定好按OK。
3. 新增完成,AVD可自由編輯或刪除。
如何啟動/安裝程式到模擬器
當程式沒錯時,即可執行程式。有兩種做法:
1. 對專案根目錄點右鍵:在選單中點選 Run As… Android Application
2. 工具列上的 Run按鈕,點選下拉式選單:Run As… Android Application
如何開啟手機權限
Android手機預設是無法安裝非 Google Play下載的程式的。因此需要做以下兩件事:
1. 設定->開發人員選項->USB偵錯(請勾選)。這時再次將手機以 USB 連上電腦會要求安裝驅動程式。
2. 設定->安全性->不明來源(請勾選)。
  
怎麼知道我的手機版本?
設定->關於手機->Android版本
開發人員選項不見了怎麼辦?(從Android 4.2之後)

到 設定->關於手機/平板電腦

不斷點選”版本號碼”,直到出現”您現在已成為開發人員!”訊息即可
再回到設定選單,就會看到”開發人員選項”了
如何確定手機連到電腦了?
點選畫面右上角的+號,點選DDMS
在畫面左側會列出目前連線的機器,下圖中有一台模擬器與一隻Samsung

[Android 補筆記] Google I/O 開發者大會所宣布的 Android Studio

在以往的學習過程當中,Android 開發環境都是先下載 Eclipse,再透過 Install New Software 去把 Android Developer Tool (ADT) 拉下來,缺點就是當全班一起在做這件事的時候,就很測試網路的極限。不過這樣作也過了很多年。

後來的作法變成下載 ADT-Bundle,其實就是裝好Android SDK 的Eclipse,下載好直接解壓縮就有最新版的Android (目前是4.2.2 API17)可以使用。如果要舊版的Android 就要另外下載。

在兩週前的 Google I/O 開發者大會,發佈了 Android Studio 0.1版,按照官方的說法是目前還在開發階段,不適合正式的程式開發。並說明 Android Studio 是基於Gradle的新型開發系統,允許使用者在IDE中及伺服器上來開發專案。它也有一個基於IntelliJ IDEA的程式編輯器,可支援智慧型編輯、進階程式開發或程式分析等。 



Android Studio具備流暢與豐富的圖形管理介面,可預覽程式在不同尺寸及平台等裝置上所呈現的樣貌(基本上我覺得這是 Android 開發者的最痛…),也讓使用者可由該IDE中更容易存取各種Google服務。這樣看來是很明顯的,雖然官方說明還是會支援在 Eclipse 上來開發 Android 專案,但日後就是會逐漸轉移到 Android Studio 來開發了,所以有需要的朋友就裝起來玩玩看吧。



有興趣的朋友可以觀看以下影片是 Google I/O 上對於 Android Studio 的發布影片


[Processing][Android] 如何讓您的Processing安裝到 Android手機?

先前文章回顧:[Processing 初體驗 – 結合Android手機]

Processing 的 Android wiki:http://wiki.processing.org/w/Android

上圖就是將 Processing 程式直接透過 Processing IDE 安裝到 Android 手機(模擬器)。

如果您想要將 Processing 的互動小程式安裝到 Android 手機上的話,只需要以下步驟就可以了:

1. 取得 Processing (http://processing.org/),下載後解壓縮找到 Processing icon 點擊就可以開啟 Processing IDE。

2. 取得 Android SDK(http://developer.android.com/sdk/index.html),下載後解壓縮即可。

3. 在  Processing 中指定 Android SDK 資料夾後,即可切換到 Android 模式。頁面的顏色會變成草綠色。

4. 直接點選左側的[Run on Device] ,Processing 會以實體Android裝置優先安裝,如果沒有的話則啟動模擬器(需使用 Android AVD Manager 新增模擬器唷!)。

    還提供了 Export Android Project 將這個Processing 程式匯出成Android專案,可在 Eclipse中開啟後新增更多有趣的功能。

5. 如果您要安裝在實體的Android裝置上,請確認您的Android裝置已開啟相關權限,電腦上也安裝了對應的驅動或同步程式。教學:http://www.appinventor.tw/phone

[leJOS教學] 感測器資訊顯示在NXT螢幕, 結合按鈕換頁

將4種感測器資訊顯示在NXT螢幕上, 結合按鈕換頁。 加入了Button.LEFT 與 Button.RIGHT的點擊事件監聽器, 藉此達到換頁的功能。

每一頁(case0~case3) 就是獨一的感測器資訊, 這樣就不用把所有的資訊都擠在同一頁了。 覺得NXT螢幕很擠的朋友可以參考本份程式碼。

螢幕截圖稍後補上~

=======================================================

import javax.microedition.lcdui.Graphics;

import lejos.nxt.Button;
import lejos.nxt.ButtonListener;
import lejos.nxt.LCD;
import lejos.nxt.LightSensor;
import lejos.nxt.SensorPort;
import lejos.nxt.SoundSensor;
import lejos.nxt.TouchSensor;
import lejos.nxt.UltrasonicSensor;
import lejos.util.Delay;

public class draw {
static int type=0;
public static void main(String[] arg){

LightSensor light=new LightSensor(SensorPort.S2);
UltrasonicSensor ultra=new UltrasonicSensor(SensorPort.S4);
TouchSensor touch=new TouchSensor(SensorPort.S1);
SoundSensor sound=new SoundSensor(SensorPort.S3);
Graphics gra=new Graphics();
int Lvalue,Uvalue,Svalue;
boolean Tvalue;
Button.ESCAPE.addButtonListener(new ButtonListener() {
public void buttonReleased(Button arg0) {System.exit(1);}
public void buttonPressed(Button arg0) {}
});

Button.LEFT.addButtonListener(new ButtonListener() {
public void buttonReleased(Button arg0) {
type–;
if(type<0){type=3;}
}
public void buttonPressed(Button arg0) {}
});

Button.RIGHT.addButtonListener(new ButtonListener() {
public void buttonReleased(Button arg0) {
type++;
if(type>3){type=0;}
}
public void buttonPressed(Button arg0) {}
});

while(true){
switch(type){
case 0:
Lvalue=light.readValue();
gra.clear();
LCD.drawString(“Light”, 1, 1);
gra.drawRect(40, 10, 10, 50);
gra.fillRect(41, 60-(int)(Lvalue/1.6), 9, (int)(Lvalue/1.6));
break;
case 1:
Uvalue=ultra.getDistance();
gra.clear();
LCD.drawString(“Ultra”, 1, 1);
gra.drawArc(25, 10, 50, 50, 0, 180);
gra.drawLine(25, 35, 75, 35);
if(Uvalue>0&&Uvalue<180){
gra.drawLine(50, 35, 50+(int)(Math.cos(Math.toRadians(Uvalue))*25), 35-(int)(Math.sin(Math.toRadians(Uvalue))*25));
}
break;
case 2:
Svalue=sound.readValue();
gra.clear();
LCD.drawString(“Sound”, 1, 1);
gra.drawLine(40, 50, 60, 50);
gra.drawLine(45, 60, 55, 60);
gra.drawLine(40, 50, 45, 60);
gra.drawLine(60, 50, 55, 60);
if(Svalue>25){gra.drawArc(40, 40, 20, 20, 45, 90);}
if(Svalue>50){gra.drawArc(35, 35, 30, 30, 45, 90);}
if(Svalue>75){gra.drawArc(30, 30, 40, 40, 45, 90);}
if(Svalue>100){gra.drawArc(25, 25, 50, 50, 45, 90);}
break;
case 3:
Tvalue=touch.isPressed();
gra.clear();
gra.drawRect(25, 10, 50, 50);
gra.drawRect(32, 17, 36, 36);
gra.drawLine(25, 10, 32, 17);
gra.drawLine(75, 60, 68, 53);
LCD.drawString(“Touch”, 1, 1);
if(Tvalue){

gra.drawLine(26,11,74,11);
gra.drawLine(27,12,73,12);
gra.drawLine(28,13,72,13);
gra.drawLine(29,14,71,14);

gra.drawLine(30,15,70,15);
gra.drawLine(31,16,69,16);

gra.drawLine(26,11,26,59);
gra.drawLine(27,12,27,58);
gra.drawLine(28,13,28,57);
gra.drawLine(29,14,29,56);
gra.drawLine(30,15,30,55);
gra.drawLine(31,16,31,54);

}
else{

gra.drawLine(74,11,74,59);
gra.drawLine(73,12,73,58);
gra.drawLine(72,13,72,57);
gra.drawLine(71,14,71,56);
gra.drawLine(70,15,70,55);
gra.drawLine(69,16,69,54);

gra.drawLine(74,59,26,59);
gra.drawLine(73,58,27,58);
gra.drawLine(72,57,28,57);
gra.drawLine(71,56,29,56);
gra.drawLine(70,55,30,55);
gra.drawLine(69,54,31,54);
}
break;
}
Delay.msDelay(500);
}

}
}

[溫故知新] Java 版的P 控制循跡機器人

Java (leJOS) 的 P控制循跡機器人, 可以得到相當順暢的循跡效果。

參考資料: http://www.inpharmix.com/jps/PID_Controller_For_Lego_Mindstorms_Robots.html

關鍵就在這兩個式子:

        vl = 200 + kp*(light.readValue() – light_initial);

vr = 200 – kp*(light.readValue() – light_initial);

1. light_initial是目標值, 也就是大約光感測器打出小紅圓圈一半位於白色場地, 一半位於黑色膠帶之上的光感測器數值。

2. light.readValue()是當下的光感測器數值, 兩者差值>0 會讓vl變小但vr變大, 機器人此時左轉, 差值愈大則機器人轉彎幅度愈大(愈接近原地旋轉)。

3. kp: 比例控制常數, 用來調整修正幅度, kp愈大機器人愈敏感。

4. 200 是基礎轉速, 就是當 light.readValue() 等於 light_initial 時, 機器人會以 200 前進。

如此機器人就能在直線是大幅減少偵測修正的次數, 並有效得知彎道的曲率。 是不是很棒呢?

來看看影片吧( NXC版本)。

============================================

import lejos.nxt.*;

public class Hy {

public static void main(String args[])
{
Button.ESCAPE.addButtonListener(new ButtonListener()
{
public void buttonPressed(Button b){System.exit(1);}
public void buttonReleased(Button b){}
});
int kp=20;
int light_initial = (30+60)/2; //half
LightSensor light = new LightSensor(SensorPort.S1);
int vl,vr;
while(true)
{

vl = 200 + kp*(light.readValue() – light_initial);
vr = 200 – kp*(light.readValue() – light_initial);
Motor.B.setSpeed(vl);
Motor.C.setSpeed(vr);
Motor.B.forward();
Motor.C.forward();
}
}
}

[leJOS] 讓機器人前進指定距離(公分) – 多執行緒

在程式中以一個變數 walk 來指定機器人行走距離, 單位為公分. 程式環境使用 leJOS

本範例重點在於將移動距離根據輪徑(5.6 cm) 轉換為馬達轉動角度, 使用 Motor.B.rotate(角度) 指令. 由於該指令屬於閉區間指令, 所以

Motor.B.rotate(180);
Motor.C.rotate(180);

會讓B馬達轉完180度之後再換C馬達旋轉180度, 機器人無法直走. 所以本範例透過兩個執行緒t1, t2分別執行 Motor.X.rotate指令, 這樣就可以讓機器人順利移動指定角度了

CAVE的 leJOS實驗室: http://lab.cavedu.com/lejos

淡江機器人Java教學網: lejosrobot2012.cavedu.com

===========================================

import lejos.nxt.*;

import lejos.util.Delay;

 

class walk

{

        public static void main(String arg[])

        {

               final double angle;

               double walk=10;

               int speed=360;

               Thread t1,t2;

               Runnable runR,runL;

 

        Button.ESCAPE.addButtonListener(new ButtonListener()

        {

        public void buttonPressed(Button b){System.exit(0);}

        public void buttonReleased(Button b){}

        });

 

        angle=(walk/(5.6d*Math.PI))*360d;

        runR=new Runnable() {

 

        public void run() {

               Motor.B.rotate((int)angle);

               }

        };

        runL=new Runnable() {

 

        public void run() {

               Motor.C.rotate((int)angle);

                }

        };

        t1=new Thread(runR);

        t2=new Thread(runL);

        t1.start();

        t2.start();

   }//main

}//class