2015年2月27日 星期五

用雷射打蚊子

台灣有些戲謔語,例如殺雞用牛刀或是用大砲打小鳥...等等,現在有人把它變成真的了。我們趕快來看看,阿督仔用雷射打蚊子

網址 https://www.youtube.com/watch?v=YnSKrzmpKGw

OpenCV 可以辨識人頭, 修改一下程式或許可以辨識蚊子, 這樣一來就可以實現用雷射打蚊子了。

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;
    }
  }
}