顯示具有 Processing 標籤的文章。 顯示所有文章
顯示具有 Processing 標籤的文章。 顯示所有文章

2016年3月15日 星期二

GaussSense 開箱文

GaussSense 是台灣 GaussToys 團隊開發的一個可以感測磁力影像的模組。這個模組應用相當廣泛,只受限於個人的想像力,這麼好的東西值得推薦。


零件清單

1.Gauss感應器與磁鐵*1
2.20cm 母母線*9
3.單排針*9
4.貼紙*3
5.名片*1


打開小紙盒,黑黑那個小方塊是感應器,圓形有藍色圖案那個是磁鐵。


下載相關資料

1.Google搜尋關鍵字「GaussToys」,點擊 Gausstoys.com 會出現官方首頁。
2.建議註冊加入開發者行列,以利後續下載動作。
3.點擊首頁中間的「加入開發者」按鈕,再點擊「下載 GaussSense SDK」。
4.分別點擊「下載 Arduino範例」與「下載 Processing SDK」。
5.安裝好 Arduino IDE 和 Processing IDE。
6.將 Processing Library 複製到 C:\Users\<使用者>\Documents\Processing\libraries資料夾內。


串接電路

GaussSense_Pin    Arduino_Pin
V                            Vcc
G                            Gnd
A                            A0
0                             2
1                             3
2                             4
3                             5



上傳Arduino程式

1. 點擊下拉功能表 檔案 > 開啟 > Mini_GaussSense_V1.ino。
2. 點擊下拉功能表 工具 > (選取Arduino板子)。
3. 點擊下拉功能表 工具 > (選取Arduino板子使用的序列埠)。
4. 點擊工具列按鈕「上傳」。


執行Processing程式

1. 點擊下拉功能表 File > Examples... > Contributed Libraries > GaussSense SDK for Processing > Basics,用滑鼠雙擊 e1_HelloGaussSense。
2. 點擊工具列按鈕「Run」。
拿起磁鐵在 GaussSense上面晃動,可以看到螢幕視窗出現數個色塊,如下圖示:



說明

1. 資料傳送方式是由 GaussSense 傳訊號給 Arduino,Arduino 再透過 USB 線的 COM 埠傳送資料給 PC 端的 Processing,再由 Processing 畫出磁力分佈圖。

2. 由於 GaussToys 公司已經在 Processing 程式裏設定自動選取可用的 COM 埠,使用者因此可以不必煩惱如何指定 COM 埠這個問題。

3. 磁鐵有兩個面,其中一面貼近GaussSense時螢幕視窗內會有藍色的色塊出現,翻轉另一面則會出現紅色色塊。色塊分佈的區域表示磁力的範圍,顏色的深淺表示磁力的強度。


2015年7月19日 星期日

將光線數據上傳到雲端(ThingSpeak)

Thingspeak.com 允許你使用網路設備即時地將數據上傳到雲端使之聚集在一起(成為資料),所以我決定要用一個簡單的光線感測器來測試這個系統。而 Processing 應用軟體剛好符合我的需求,可以透過它操控網路攝影機來偵測人的移動,然後將結果上傳到  ThingSpeak 頻道。


開始前的測試

首先,下載這個簡單的程式,你可以透過它和 ThingSpeak.com 從事簡單的聯繫:

https://drive.google.com/file/d/0B2ZbLCPalrgEZWZjNWMxYjYtZTZmYS00YTExLThkNWYtYzI0ZjYxYWY4YzRm/view?ddrp=1&hl=en#

你可以用鍵盤隨便打幾個數字,這些數字將會被上傳到 ThingSpeak.com,如果出現下列畫面表示可以正常工作。




上傳光線感測數據

在這兒我們會使用 LDR 去偵測光線的強度,請依照下列電路圖在麵包板上插妥零件與接線。


底下這個程式很簡單,它單純地只是把 A0 腳位的值透過序列埠傳送出去,程式如下:

void setup(){
  Serial.begin(9600);
}

void loop(){
  Serial.println(analogRead(0));
  delay(2000);
}

請您將上述程式複製並貼到 Arduino IDE 裡,並上傳到板子。


接收數據

我們要用 Processing 來接收這些數據,需要變更一些程式碼,如下:

/**
 * Tests the thinkspeak channel by sending any numeric
 * keypress using the specified APIKEY and FIELD
 */

import processing.serial.*;
import processing.net.*;

//CONFIGURATION
String APIKEY = "YOURAPI"; //your api key
String FIELD = "field1";
int PORTNUM = 0; //port number of your arduino
//END CONFIGURATION

Serial arduino;
Client c;
String data;
int number; //read from arduino

void setup() {
  size(600, 400);

  //setup the serial port
  // List all the available serial ports:
  println(Serial.list());
  //Init the Serial object
  arduino = new Serial(this, Serial.list()[PORTNUM], 9600);

  // The font must be located in the sketch's
  // "data" directory to load successfully
  PFont font;
  font = loadFont("Monaco-12.vlw");
  textFont(font);
}

void draw() {
  background(50);
  fill(255);
  text("ThinkSpeak Processor", 10, 20);

  fill(0, 255, 0);
  text("Light Value Read:  " + number, 10, 40);

  if( data != null ) {
    fill(0, 255, 0);
    text("Server Response:", 10, 60);
    fill(200);
    text(data, 10, 80);
  }
  if(c != null) {
    if (c.available() > 0) { // If there's incoming data from the client...
      data = c.readString(); // ...then grab it
      println(data);
    }
  }

  //if we have a new line from our arduino, then send it to the server
  String ln;
  if( (ln = arduino.readStringUntil('\n')) != null) {
    try {
      number = new Integer(trim(ln));
      if(number < 1025) {
        println("Writing " + number);
        sendNumber(number);
      }
    }
    catch(Exception ex) {
    }
  }
}

void sendNumber(float num) {
  c = new Client(this, "api.thingspeak.com", 80); // Connect to server on port 80
  c.write("GET /update?key="+APIKEY+"&"+FIELD+"=" + num + " HTTP/1.1\n");
  c.write("Host: my_domain_name.com\n\n"); // Be polite and say who we are
}

請您將上述程式複製並貼到 Processing IDE 裡,並執行它。

如果你看到下列畫面,其中 Light Value Read:的值每 2 秒跳動一次,那麼恭喜你,你成功了。


















2015年6月28日 星期日

蘋果的智慧 - Part2.2 再談移動

不知您有沒有發現到,在上一章裡初級智慧動物像無頭蒼蠅那樣隨意亂竄,這是因為它沒有目標可以追尋。在本章裡,我們將利用滑鼠游標代表另一隻動物,而具有初級智慧的那隻動物會來追逐牠。


取得滑鼠游標座標

系統變數 mouseX 和 mouseY 分別表示滑鼠的 X 座標和 Y 座標。當移動滑鼠時,您所取得的 mouseX 和 mouseY 數值也會跟著改變。

這兒我們要讓初級智慧動物追逐游標,游標移動到哪裡牠便跟著移動到那裡,程式碼如下:

int cx, cy;
int vx, vy;

void setup() {
  size(800,600);
  cx = width / 2;
  cy = height / 2;
}

void draw() {
  background(155);
  if (mouseX > cx)
    vx = 1;
  else
    vx = -1;
  if (mouseY > cy)
    vy = 1;
  else
    vy = -1;
  cx += vx;
  cy += vy;
  rect(cx, cy, 5, 5);
}




蘋果的智慧 - Part2.1 移動

本章旨在探討初級智慧動物如何移動。

在說明如何移動之前,我們要先瞭解 Processing 的座標系統。Processing 是以螢幕的左上角落為座標原點 (0, 0),水平方向為 X 軸,往右為正(+),往左為負(-);垂直方向為 Y 軸,往下為正(+),往上為負(-)。旋轉方向順時針為正(+),逆時針為負(-)。您可以參考 https://processing.org/tutorials/drawing/


最初出現的地方

為了方便觀察,最開始我們會將初級智慧動物置放於螢幕中央,如此牠不至於很快就走出螢幕而消失不見。程式碼如下:

size(800, 600)       // 設置螢幕大小,水平為 800 單位,垂直為 600 單位
int cx = width / 2      // cx 表動物目前的水平座標位置
int cy = height / 2     // cy 表動物目前的垂直座標位置

width 和 height 都是公用變數,其意思分別是螢幕的水平尺寸和垂直尺寸,在此處也就是 800 x 600。

如果我們希望初級智慧動物是隨意出現在螢幕的任一角落,我們可以使用亂數函式 random,程式碼可以修改如下:

size(800, 600)       // 設置螢幕大小,水平為 800 單位,垂直為 600 單位
int cx = (int)random(0, width)      // cx 表動物目前的水平座標位置
int cy = (int)random(0, height)     // cy 表動物目前的垂直座標位置

因為 random 傳回的值是 float 的格式,為了要配合 cx 和 cy 的 int 格式,所以我們要在前面加上 (int) 做格式轉換的動作。

然後,我們畫出一個 5x5 單位的正方形來代表初級智慧動物,程式碼如下:

rect(cx, cy, 5, 5);

完整程式碼如下:

int cx, cy;

void setup() {
  size(800,600);
  cx = width / 2;
  cy = height / 2;
}

void draw() {
  rect(cx, cy, 5, 5);
}



更改為隨機出現在任一位置,完整程式碼如下:

int cx, cy;

void setup() {
  size(800,600);
  frameRate(2); // 指定影格速率,每秒執行 2 次 draw 函式
}

void draw() {
  background(155);  // 指定背景顏色,此處有刷新螢幕的作用
  cx = (int)random(0, width);
  cy = (int)random(0, height);
  rect(cx, cy, 5, 5);
}


移動碼

初級智慧動物會依據移動碼的數值來移動。移動碼又可分為水平分量與垂直分量。分量的值愈大表移動速度愈快,反之則愈慢,若為 0 則表示靜止不動。

我們用變數 xv 和 yv 分別代表水平分量和垂直分量的移動值,將位置變數 cx 和 cy 分別加入變數 vx 和 vy,就可以讓初級智慧動物產生移動的效果。

移動有方向性,所以 xv 和 yv 有正負的分別。另外為了限制移動的速度,此處我們將移動分量暫時限定於 -5 ~ 5 之間。

程式碼如下:

int vx = (int)random(-5, 5);
int vy = (int)random(-5, 5);
cx += vx;
cy += vy;


完整程式碼如下:

int cx, cy;

void setup() {
  size(800,600);
  cx = width / 2;
  cy = height / 2;
  frameRate(10);
}

void draw() {
  background(155);
  int vx = (int)random(-5, 5);
  int vy = (int)random(-5, 5);
  cx += vx;
  cy += vy;
  rect(cx, cy, 5, 5);
}


延伸閱讀

亂數 random 函式 https://processing.org/reference/random_.html








蘋果的智慧 - Part1 智慧的分級

「蘋果的智慧」這本書將機器智慧概分為初級智慧與中級智慧。

初級智慧動物會隨機取得一個指令,告訴他該往右、往左或往其他方向移動,另外還會隨機取得移動的速度。

中級智慧動物除了俱備初級智慧動物所有的屬性之外,它最特別的是有記憶功能,它會學習,可以透過記憶資料庫告訴他在面對問題時該怎麼做。

蘋果的智慧 - Part0 前言

作者黃松榮於民國72年12月出版一本書,書名叫「蘋果的智慧」,這本書在我書架內已塵封30幾年了,最近在臉書看到一篇有關人工智慧的貼文,剛好我這幾年來也在玩自走車和機器人,心想或許能為機器人加入一些人工智慧,於是就把這本書再重新翻出來看看。

這本「頻果的智慧」書中所謂的人工智慧,前面幾個章節僅僅只是模擬動物如何移動、搜尋、獵殺或躲避,最後一個章節則加入記憶。若以現今的電腦遊戲設計方法來看,書中所謂的人工智慧只能算是幼稚園等級。雖然如此,它還是有很多地方值得初學者來學習的。

「頻果的智慧」書中的範例程式是用 APPLE BASIC 寫的,我個人覺得 Processing 這種自然語言比 BASIC 更能表現圖形和動態效果,所以如果對人工智慧有興趣卻又不瞭解 Processing 程式語言的人可能得花更多時間和精神在這上面。

人工智慧 (Artificial Intelligence) 簡稱AI,我不多作解釋,建議您可以看一下維基百科,文中說明得非常詳細,網址 https://zh.wikipedia.org/wiki/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD


「頻果的智慧」目錄如下:

第1章  智慧的分級
第2章  移動與前往搜尋
第3章  初級智慧
第4章  初級智慧的互相結合
第5章  中級智慧
第6章  機器心理學簡介
第7章  蒐集編譯資料

本人會依據上述章節陸續來探討人工智慧。

2015年5月7日 星期四

枚舉(enum)

如果我們能善加使用 enum 的功能,產生更短的且可讀性更好的代碼,將是非常有益的

我們知道 Java 支援 enum 語法,但其實 Processing 並不支援 enum 語法。雖然您可以在 Processing IDE 裏看到 enum 這個關鍵字會變色,而且您也遵循它的使用規則建構枚舉資料,可是在編譯時它會產生這樣的錯誤:

Unrecognized type:46 (ENUM_DEF)

雖然如此,我們還是可以找出一個辦法來解決這個問題。從現在起您必須記住,您無法像 Java 那樣把 enum 跟主程式寫在一起,而必須把 enum 寫在另外一個頁籤(Tab),然將它的延伸檔名命名為 .java 即可,如下:

主程式:

Day day;
         
void setup() {
  println(day.FRIDAY);
}

void draw(){}


新建一個頁籤,並將它命名為 Day.java

public enum Day {
  SUNDAY, 
  MONDAY,
  TUESDAY, 
  WEDNESDAY, 
  THURSDAY, 
  FRIDAY, 
  SATURDAY

}; 


start()

一般寫 Processing 程式的人都知道,一個最基本的程式架構必須包括 setup() 和 draw() 這兩個函式,如下:

void setup() {
}

void draw() {
}

而且一直以來都以為第一個執行的函式是 setup(),其實不是如此。

請您將下列程式碼鍵入 IDE 並執行,

void start() {
  println("start");
}

void setup() {
  println("setup");
}

void draw() {
}

結果您會發現訊息欄印出的是

start
setup

所以結論是:

第一個執行的函式是 start(),Processing 主要是用它來做初始化的動作,接著才是執行 setup()。

那麼問題來了,Arduino 是否也隱藏有這樣的玄機嗎?








2015年5月5日 星期二

讀取 Yahoo 氣象資訊

Yahoo 網站提供免費的氣象資訊,包括溫度、濕度、風速、風向、能見度和大氣壓力...等,我們可以使用 Processing 取回這些資訊,將它顯示在電腦螢幕上,或是傳給 Arduino 等互動裝置。


下載 Library

切換到網頁 https://github.com/onformative/YahooWeather ,點選右下角落的「Download ZIP」按鈕。或是點按網址 http://www.onformative.com/uploads/googleWeather/YahooWeather.zip 直接下載。

下載後解壓縮,並將他複製到 <Processing>/libraries 資料夾內。最後,別忘了要退出 Processing 再重新啟動。


開啟範例圖檔

內建的範例程式可以讓您快速感受到取得氣象資訊是多麼容易的一件事。

點按下拉功能表 File > Examples...,再展開 Contributed Libraries > Yahoo Weather 並雙擊 WeatherSimpleExample。

程式碼如下:

import com.onformative.yahooweather.*;

YahooWeather weather;
int updateIntervallMillis = 30000;

void setup() {
  size(700, 300);
  fill(0);
  textFont(createFont("Arial", 14));
  // 2442047 = the WOEID of Berlin
  // use this site to find out about your WOEID : http://sigizmund.info/woeidinfo/
  weather = new YahooWeather(this, 638242, "c", updateIntervallMillis);
}

void draw() {
  weather.update();

  background(255);
  text("City: "+weather.getCityName()+"; Region: "+weather.getRegionName()+"; Country: "+weather.getCountryName()+"; Last updated: "+weather.getLastUpdated(), 20, 20);
  text("Lon: "+weather.getLongitude()+" Lat: "+weather.getLatitude(), 20, 40);
  text("WindTemp: "+weather.getWindTemperature()+" WindSpeed: "+weather.getWindSpeed()+" WindDirection: "+weather.getWindDirection(), 20, 60);
  text("Humidity: "+weather.getHumidity()+" visibility: "+weather.getVisibleDistance()+" pressure: "+weather.getPressure()+" rising: "+weather.getRising(), 20, 80);
  text("Sunrise: "+weather.getSunrise()+" sunset: "+weather.getSunset(), 20, 100);
}

public void keyPressed() {
  if (key == 'q') {
    weather.setWOEID(638242);
  }
  if (key == 'r') {
    weather.setWOEID(44418);
  }
}

點擊「Run」按鈕執行程式,就可以看到如下畫面:


目前顯示的是德國柏林(Berlin)的天氣,按下鍵盤的 'r' 鍵可以顯示英國倫敦(London)的天氣,按下鍵盤的 'q' 鍵可以再顯示柏林的天氣。



顯示台灣城市天氣資訊

要顯示各地區氣象資訊的關鍵是甚麼? 答案是「WOE ID」,只要改變 WOE ID 就可以顯示不同區域的氣象資訊。

範例程式中德國柏林(Berlin)的 WOEID 是 638242,英國倫敦(London)的 WOE ID 是 44418,那麼台北的 WOE ID 是多少呢? 您可以到這個網頁

https://weather.yahoo.com/taiwan/

選擇清單中的台灣各地區城市。

我們以台北為例,請您點按 Taipei City,在新頁面內再點按一次 Taipei City,網頁會跳到

https://weather.yahoo.com/taiwan/taipei-city/taipei-city-2306179/

網址最後面的數字就是台北的 WOE ID。



您可以用這組數字取代掉程式碼中的 638242,如下兩行:

weather = new YahooWeather(this, 638242, "c", updateIntervallMillis);

weather.setWOEID(638242);

如果要查其他地方的 WOEID,可以直接在搜尋欄位內鍵入地名或郵遞區號。


我們再以桃園為例,在搜尋欄位內鍵入「taoyuan」,就可以得到網址

https://weather.yahoo.com/taiwan/taoyuan-county/taoyuan-city-2298866/

所以桃園的 WOE ID 為 2298866。


最後,我們要顯示台北和桃園的氣象資訊,程式碼如下:

import com.onformative.yahooweather.*;

YahooWeather weather;
int updateIntervallMillis = 30000;

void setup() {
  size(700, 300);
  fill(0);
  textFont(createFont("Arial", 14));
  weather = new YahooWeather(this, 2298866, "c", updateIntervallMillis);
}

void draw() {
  weather.update();

  background(255);
  text("City: "+weather.getCityName()+"; Region: "+weather.getRegionName()+"; Country: "+weather.getCountryName()+"; Last updated: "+weather.getLastUpdated(), 20, 20);
  text("Lon: "+weather.getLongitude()+" Lat: "+weather.getLatitude(), 20, 40);
  text("WindTemp: "+weather.getWindTemperature()+" WindSpeed: "+weather.getWindSpeed()+" WindDirection: "+weather.getWindDirection(), 20, 60);
  text("Humidity: "+weather.getHumidity()+" visibility: "+weather.getVisibleDistance()+" pressure: "+weather.getPressure()+" rising: "+weather.getRising(), 20, 80);
  text("Sunrise: "+weather.getSunrise()+" sunset: "+weather.getSunset(), 20, 100);
}

public void keyPressed() {
  if (key == 'q') {
    weather.setWOEID(2298866);
  }
  if (key == 'r') {
    weather.setWOEID(2306179);
  }
}


相關文章

Onformative http://www.onformative.com/lab/google-weather-library-for-processing/

Python Weather API https://code.google.com/p/python-weather-api/





2015年3月12日 星期四

Library - Hermes

Hermes 核心提供一個獨特的系統用來管理遊戲。除了核心框架,它還包括有碰撞檢測,物理,鍵盤,鼠標,聲音和動畫等控制模組。

您可以到官網並移動滑桿到網頁最底端,就可以看到 Hermes 做出的一些動畫效果。

官網 http://rdlester.github.io/hermes/


下載

有數種下載的方式:
1. 這個網址下載函式庫 http://rdlester.github.com/hermes/downloads/hermes.zip
2. 這兒也可以下載 https://github.com/rdlester/hermes/
3. 個人比較建議用 Processing IDE 下載與安裝。步驟如下:
點擊下拉功能表 Sketch > Import Library...> Add Libary...,移動滑桿到 Hermes 項目並點擊該項目與 Install 按鈕。




手動安裝

如果不是使用上述第3種方式下載,您也可以手動安裝,步驟如下。
將 hermes-master.zip 解壓縮後,將該資料夾名稱更名為 hermes 並將整個資料夾複製貼到 <Processing 路徑>\libraries 裏。
記得要關閉 Processing 系統並重新啟動後,Hermes 這個函式庫才會出現唷。


教學

教學說明在下方的網址
https://github.com/rdlester/hermes/wiki/Tutorial-Pt.-0:-Before-Getting-Started

或是您也可以開啟範例檔案先執行看看 Hermes 它有哪些令人驚喜的地方,
點擊下拉功能表 File > Examples...> Contributed Libraries > Hermes,雙擊 tutorialA


點擊工具列按鈕 Run,接著您就可以看到執行的結果,如下圖



問題與對策

執行時如果出現如下圖之訊息,有可能的原因是您使用的 Processsing 版本太老舊了,建議您換用最新版本執行。


2015年3月11日 星期三

使用者介面 - G4PTool

這是一款視覺化的圖形介面編輯器,它使用的方式跟一般圖形介面建構軟體差不多,都是使用拖拉方式將工具拖拉到視窗內。它雖然操作簡單方便,但不適用於 Android。如果只是想寫 JAVA 程式,是可以考慮這個。

官網 http://lagers.org.uk/g4ptool/index.html


下載與安裝

下載網址 http://sourceforge.net/projects/guibuilder/files/?source=navbar。
我比較建議您使用下列方式下載與安裝。
1. 點擊下拉功能表 Tools > Add Tool...
2. 往下拉動滑桿並點擊 G4PTool 這一項,再點擊 Install 按鈕


3. 如果出現 Remove 按鈕,表示已安裝完成。
4. 退出 Processing 並重新啟動。


範例

1. 點擊下拉功能表 Files > Examples...,出現視窗


2. 展開 G4P,快擊二下 G4P_ImageButton 開啟文件
3. 點擊 Run 工具列按鈕,即可看見如下畫面



設計自己的 GUI

1. 點擊下拉功能表 Tools > GUI builder,出現視窗


2. 點擊工具列的 Button 鈕,用滑鼠將 Button 稍微移動到旁邊,並再點擊一次 Button 鈕。您可以看見如下圖


3. 點擊 Processing IDE,您可以看見新增兩個頁籤,其中一個是 gui。另外,原本空白的編輯區裏面已經佈滿了程式碼,這是自動產生的。
如果您對 gui 頁籤裏的程式碼還不熟悉,建議您不要隨意變更該程式碼內容。


4. 點擊主頁籤 sketch_xxxx,再點擊工具列按鈕 Run,即可看見如下畫面


使用者介面 - ControlP5

ControlP5 算是比較多人使用的 GUI 其中一種,它也可以適用於 Android 模式,鄭重推薦給您。

官網 http://www.sojamo.de/libraries/controlP5/


下載

下載網址 http://www.sojamo.de/libraries/controlP5/download/controlP5-2.0.4.zip。
我比較建議您使用下列方式下載與安裝。
1. 點擊下拉功能表 Sketch > Import Library...> Add Library...
2. 往下拉動滑桿並點擊 ControlP5 這一項,再點擊 Install 按鈕


3. 如果出現 Remove 按鈕,表示已安裝完成。
4. 退出 Processing 並重新啟動。


範例

1. 點擊下拉功能表 Files > Examples...,出現視窗


2. 展開 ControlP5/controllers,快擊二下 ControllP5button 開啟文件
3. 點擊 Run 工具列按鈕,即可看見如下畫面










使用者介面 - pUI

一個好的使用者圖形介面可以讓您的程式更加好用,我想這個就是您迫切需要的吧?



官網 http://martinleopold.com/pui/
下載 https://github.com/martinleopold/pUI


安裝

將 pUI-master.zip 解壓縮後,將資料夾 pUI-master 更名為 pUI,再將整個資料夾放到 LIbraries 裏,退出 Processing 並重新啟動。




2015年3月7日 星期六

Android 版的 Procesing

終於可以直接在 Android 作業系統上面使用 Procesing IDE 寫程式了。

下載 Android APP https://play.google.com/store/apps/details?id=com.calsignlabs.apde


您可能對這個也有興趣

Android 版的 Processing 編輯器 https://play.google.com/store/apps/details?id=com.kwipi.processing_free





2015年2月9日 星期一

Blink

透過 Processing 讓 Arduino 位於 pin 13 上面的 LED 閃爍。

原文詳 http://playground.arduino.cc/Interfacing/Processing


Arduino Code

請開啟並上載 File > Examples > Firmata > StandardFirmata.ino


Processing Code

import processing.serial.*;
import cc.arduino.*;

Arduino arduino;
int ledPin = 13;

void setup()
{
  //println(Arduino.list());
  arduino = new Arduino(this, Arduino.list()[0], 57600);
  arduino.pinMode(ledPin, Arduino.OUTPUT);
}

void draw()
{
  arduino.digitalWrite(ledPin, Arduino.HIGH);
  delay(1000);
  arduino.digitalWrite(ledPin, Arduino.LOW);
  delay(1000);
}

靜聽花開的聲音

這是一個 Arduino 與 Processing 互動的實例,改變 Arduino A0 pin 輸出的值就可以讓 Processing 裏的樹狀結構改變形狀。

原文詳 http://playground.arduino.cc/Interfacing/ProcesssHackForFirmata



Arduino Code

請開啟並上載 File > Examples > Firmata > StandardFirmata.ino


Processing Code

/*
* Recursive Tree
 * by Daniel Shiffman
 *
 * Renders a simple tree-like structure via recursion
 * Branching angle calculated as a function of horizontal mouse  location
 */
import processing.serial.*; // reference the serial library

import cc.arduino.*; // reference the arduino library

Arduino arduino; // create a variable arduino of the Arduino data type

float theta;
void setup() {
  size(200, 200);
  smooth();
  println(Serial.list()); // List all the available serial ports:

  //arduino = new Arduino(this, Arduino.list()[0], 57600);
  arduino = new Arduino(this, "COM4", 57600);
}

void draw() {

  background(0);
  frameRate(30);
  stroke(255);
  // Let's pick an angle 0 to 90 degrees based on the mouse position
  /* float a = (mouseX / (float) width) * 90f; // original line */

  float a = (arduino.analogRead(0) / (float) width) * 90f;

  // Convert it to radians
  theta = radians(a);
  // Start the tree from the bottom of the screen
  translate(width/2, height);
  // Draw a line 60 pixels
  line(0, 0, 0, -60);
  // Move to the end of that line
  translate(0, -60);
  // Start the recursive branching!
  branch(60);
}

void branch(float h) {
  // Each branch will be 2/3rds the size of the previous one
  h *= 0.66f;

  // All recursive functions must have an exit condition!!!!
  // Here, ours is when the length of the branch is 2 pixels or less
  if (h > 2) {
    pushMatrix();    // Save the current state of transformation (i.e. where are we now)
    rotate(theta);   // Rotate by theta
    line(0, 0, 0, -h);  // Draw the branch
    translate(0, -h); // Move to the end of the branch
    branch(h);       // Ok, now call myself to draw two new branches!!
    popMatrix();     // Whenever we get back here, we "pop" in order to restore the previous matrix state

    // Repeat the same thing, only branch off to the "left" this time!
    pushMatrix();
    rotate(-theta);
    line(0, 0, 0, -h);
    translate(0, -h);
    branch(h);
    popMatrix();
  }
}


建議您

你也可以把 Processing Code 這一行

 float a = (arduino.analogRead(0) / (float) width) * 90f;

改成

float a = (mouseX / (float) width) * 90f;

如此,即可不必透過讀取 Arduino A0 pin 的值,只要左右移動滑鼠就可以改變樹的形狀。






2015年2月1日 星期日

踏出互動的第一步 - 串行呼叫與回應

對話是溝通的開始,你講你的英文我講我的拉丁文,牛頭不對馬嘴這樣是不行的。
除了你講的我能懂,我講的你也能懂之外,還要建立起彼此間說話的規則,否則你一句我也來一句,這樣有講等於沒講。
另外一點是,兩個人說話總有一方先起頭,另一方才隨後附和,所以就變成有主從關係。通常主方會持續發出「我想和你說話,你知道了嗎?如果知道了,那麼我可以開始說了嗎?」類似這樣的訊息,而從方則會持續發出「你是在跟我說話嗎?如果是的話那麼你可以開始說了。」類似這樣的訊息。
想要讓 Arduino 和 Processing 這兩個軟體彼此有良好的溝通,也必須透過上述所講的方式進行。

本文示範讓 Arduino 和 電腦端的 Processing 互傳多字節資料。一開始 Arduino 會先持續傳送一個 ASCII 碼 'A' 給 Processing,直到 Processing 有了回應,Arduino 才會繼續後續的動作。

你可以利用連接在 Arduino 上面的兩個電位器移動電腦上的小白點,也可以按下按鈕讓小白點消失或是出現。

原文 http://arduino.cc/en/Tutorial/SerialCallResponse




電路圖


Arduino Code

/*
  Serial Call and Response
 Language: Wiring/Arduino

 This program sends an ASCII A (byte of value 65) on startup
 and repeats that until it gets some data in.
 Then it waits for a byte in the serial port, and
 sends three sensor values whenever it gets a byte in.

 Thanks to Greg Shakar and Scott Fitzgerald for the improvements

 The circuit:
 * potentiometers attached to analog inputs 0 and 1
 * pushbutton attached to digital I/O 2

 Created 26 Sept. 2005
 by Tom Igoe
 modified 24 April 2012
 by Tom Igoe and Scott Fitzgerald

 This example code is in the public domain.

 http://www.arduino.cc/en/Tutorial/SerialCallResponse

 */

int firstSensor = 0;    // first analog sensor
int secondSensor = 0;   // second analog sensor
int thirdSensor = 0;    // digital sensor
int inByte = 0;         // incoming serial byte

void setup()
{
  // start serial port at 9600 bps:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

  pinMode(2, INPUT);   // digital sensor is on digital pin 2
  establishContact();  // send a byte to establish contact until receiver responds
}

void loop()
{
  // if we get a valid byte, read analog ins:
  if (Serial.available() > 0) {
    // get incoming byte:
    inByte = Serial.read();
    // read first analog input, divide by 4 to make the range 0-255:
    firstSensor = analogRead(A0)/4;
    // delay 10ms to let the ADC recover:
    delay(10);
    // read second analog input, divide by 4 to make the range 0-255:
    secondSensor = analogRead(1)/4;
    // read  switch, map it to 0 or 255L
    thirdSensor = map(digitalRead(2), 0, 1, 0, 255);
    // send sensor values:
    Serial.write(firstSensor);
    Serial.write(secondSensor);
    Serial.write(thirdSensor);            
  }
}

void establishContact() {
  while (Serial.available() <= 0) {
    Serial.print('A');   // send a capital A
    delay(300);
  }
}


Processing Code

// This example code is in the public domain.

import processing.serial.*;

int bgcolor;                 // Background color
int fgcolor;                 // Fill color
Serial myPort;                       // The serial port
int[] serialInArray = new int[3];    // Where we'll put what we receive
int serialCount = 0;                 // A count of how many bytes we receive
int xpos, ypos;                  // Starting position of the ball
boolean firstContact = false;        // Whether we've heard from the microcontroller

void setup() {
  size(256, 256);  // Stage size
  noStroke();      // No border on the next thing drawn

  // Set the starting position of the ball (middle of the stage)
  xpos = width/2;
  ypos = height/2;

  // Print a list of the serial ports, for debugging purposes:
  println(Serial.list());

  // I know that the first port in the serial list on my mac
  // is always my  FTDI adaptor, so I open Serial.list()[0].
  // On Windows machines, this generally opens COM1.
  // Open whatever port is the one you're using.
  String portName = Serial.list()[0];
  myPort = new Serial(this, portName, 9600);
}

void draw() {
  background(bgcolor);
  fill(fgcolor);
  // Draw the shape
  ellipse(xpos, ypos, 20, 20);
}

void serialEvent(Serial myPort) {
  // read a byte from the serial port:
  int inByte = myPort.read();
  // if this is the first byte received, and it's an A,
  // clear the serial buffer and note that you've
  // had first contact from the microcontroller.
  // Otherwise, add the incoming byte to the array:
  if (firstContact == false) {
    if (inByte == 'A') {
      myPort.clear();          // clear the serial port buffer
      firstContact = true;     // you've had first contact from the microcontroller
      myPort.write('A');       // ask for more
    }
  }
  else {
    // Add the latest byte from the serial port to array:
    serialInArray[serialCount] = inByte;
    serialCount++;

    // If we have 3 bytes:
    if (serialCount > 2 ) {
      xpos = serialInArray[0];
      ypos = serialInArray[1];
      fgcolor = serialInArray[2];

      // print the values (for debugging purposes only):
      println(xpos + "\t" + ypos + "\t" + fgcolor);

      // Send a capital A to request new sensor readings:
      myPort.write('A');
      // Reset serialCount:
      serialCount = 0;
    }
  }
}



2015年1月28日 星期三

移動滑鼠開/關 LED

移動滑鼠到畫面中的小方塊裏面,就會點亮 LED,移開滑鼠 LED 會跟著變暗。

原文詳 http://arduino.cc/en/Tutorial/PhysicalPixel


電路圖




Arduino Code

/*
  Physical Pixel

 An example of using the Arduino board to receive data from the
 computer.  In this case, the Arduino boards turns on an LED when
 it receives the character 'H', and turns off the LED when it
 receives the character 'L'.

 The data can be sent from the Arduino serial monitor, or another
 program like Processing (see code below), Flash (via a serial-net
 proxy), PD, or Max/MSP.

 The circuit:
 * LED connected from digital pin 13 to ground

 created 2006
 by David A. Mellis
 modified 30 Aug 2011
 by Tom Igoe and Scott Fitzgerald

 This example code is in the public domain.

 http://www.arduino.cc/en/Tutorial/PhysicalPixel
 */

const int ledPin = 13; // the pin that the LED is attached to
int incomingByte;      // a variable to read incoming serial data into

void setup() {
  // initialize serial communication:
  Serial.begin(9600);
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
}

void loop() {
  // see if there's incoming serial data:
  if (Serial.available() > 0) {
    // read the oldest byte in the serial buffer:
    incomingByte = Serial.read();
    // if it's a capital H (ASCII 72), turn on the LED:
    if (incomingByte == 'H') {
      digitalWrite(ledPin, HIGH);
    }
    // if it's an L (ASCII 76) turn off the LED:
    if (incomingByte == 'L') {
      digitalWrite(ledPin, LOW);
    }
  }
}


Processing Code

// mouseover serial

// Demonstrates how to send data to the Arduino I/O board, in order to
// turn ON a light if the mouse is over a square and turn it off
// if the mouse is not.

// created 2003-4
// based on examples by Casey Reas and Hernando Barragan
// modified 30 Aug 2011
// by Tom Igoe
// This example code is in the public domain.



import processing.serial.*;

float boxX;
float boxY;
int boxSize = 20;
boolean mouseOverBox = false;

Serial port;

void setup() {
  size(200, 200);
  boxX = width/2.0;
  boxY = height/2.0;
  rectMode(RADIUS);

  // List all the available serial ports in the output pane.
  // You will need to choose the port that the Arduino board is
  // connected to from this list. The first port in the list is
  // port #0 and the third port in the list is port #2.
  println(Serial.list());

  // Open the port that the Arduino board is connected to (in this case #0)
  // Make sure to open the port at the same speed Arduino is using (9600bps)
  port = new Serial(this, "COM5", 9600);
}

void draw()
{
  background(0);

  // Test if the cursor is over the box
  if (mouseX > boxX-boxSize && mouseX < boxX+boxSize &&
    mouseY > boxY-boxSize && mouseY < boxY+boxSize) {
    mouseOverBox = true;
    // draw a line around the box and change its color:
    stroke(255);
    fill(153);
    // send an 'H' to indicate mouse is over square:
    port.write('H');
  }
  else {
    // return the box to it's inactive state:
    stroke(153);
    fill(153);
    // send an 'L' to turn the LED off:
    port.write('L');    
    mouseOverBox = false;
  }

  // Draw the box
  rect(boxX, boxY, boxSize, boxSize);
}


提醒您

1. 雖然電路圖的 LED 是插在 pin 13,但因為 Arduino 板子上面的 pin 13 已經內建一只 LED,所以您也可以不必插入任何 LED,只要觀察 Arduino 板子上面的 LED 即可。
2. 檢查 COM 埠有沒有正確。
3. 檢查 鮑率 是不是 9600。

移動滑鼠控制 LED 明暗

您可以透過左右移動滑鼠來控制 LED 的明暗,往右變亮,往左變暗。

原文詳 http://arduino.cc/en/Tutorial/Dimmer


電路圖



Arduino Code

const int ledPin = 9;      // the pin that the LED is attached to

void setup()
{
  // initialize the serial communication:
  Serial.begin(9600);
  // initialize the ledPin as an output:
  pinMode(ledPin, OUTPUT);
}

void loop() {
  byte brightness;

  // check if data has been sent from the computer:
  if (Serial.available()) {
    // read the most recent byte (which will be from 0 to 255):
    brightness = Serial.read();
    // set the brightness of the LED:
    analogWrite(ledPin, brightness);
  }
}


Processing Code

// Dimmer - sends bytes over a serial port
// by David A. Mellis
//This example code is in the public domain.

import processing.serial.*;
Serial port;

void setup() {
  size(256, 150);

  println("Available serial ports:");
  println(Serial.list());

  // Uses the first port in this list (number 0).  Change this to
  // select the port corresponding to your Arduino board.  The last
  // parameter (e.g. 9600) is the speed of the communication.  It
  // has to correspond to the value passed to Serial.begin() in your
  // Arduino sketch.
  port = new Serial(this, "COM5", 9600);

  // If you know the name of the port used by the Arduino board, you
  // can specify it directly like this.
  //port = new Serial(this, "COM1", 9600);
}

void draw() {
  // draw a gradient from black to white
  for (int i = 0; i < 256; i++) {
    stroke(i);
    line(i, 0, i, 150);
  }

  // write the current X-position of the mouse to the serial port as
  // a single byte
  port.write(mouseX);
}


提醒您

1. LED 要插在 pin 9,或是其它 PWM 埠。
2. 檢查 COM 埠有沒有正確。
3. 檢查 鮑率 是不是 9600。


建議

您也可以修改程式碼,把它改成可以控制舵機角度。






2015年1月22日 星期四

畫出頻率圖形

用 Arduino 偵測頻率,並畫出圖形。

電路接法:




下載頻率程式庫 http://interface.khm.de/wp-content/uploads/2009/01/FreqCounter_1_12.zip

首先我們先來練習如何偵測頻率,請將下列程式貼到 Arduino IDE 裏:

#include <FreqCounter.h>

void setup() {
  Serial.begin(57600);                    // connect to the serial port
  Serial.println("Frequency Counter");
}

long int frq;
Void loop() {

  FreqCounter::f_comp= 8;             // Set compensation to 12
  FreqCounter::start(100);            // Start counting with gatetime of 100ms
  while (FreqCounter::f_ready == 0)         // wait until counter ready

    frq=FreqCounter::f_freq;            // read result
  Serial.println(frq);                // print result
  delay(20);
}


接下來我們要將頻率數據畫出圖形,您可以用 Processing、Python、C 或 Matplotlib 等程式化出圖形。

在這裡我將介紹使用 Bridge Control Panel 軟體化出圖形。

下載 Bridge Control Panel http://www.cypress.com/?rID=38050

畫出的圖形如下:



原文詳:
1. http://interface.khm.de/index.php/lab/interfaces-advanced/arduino-frequency-counter-library/
2. http://www.instructables.com/id/Plotting-Data-From-Arduino/