05 2月

距離を測る


距離計は、相手に光を当てて反射して帰ってくる時間で距離を測ることができるんだ。

準備するもの

名前 仕様
マイコン Arduino UNO
距離計 Sharp 製 Infrared Proximity Sensor Short Range – Sharp GP2D120XJ00F

回路図を示す。

arduino_distance-sensor-fig1arduino_distance-sensor-fig1

電圧と距離の関係
arduino_distance-sensor-fig2arduino_distance-sensor-fig2

変換表

bit  \Rightarrow v
v = x \times (\frac{ 5}{1024})

区間 (v) 変換式
\ge 2.0 L = -2.86 \times v + 11.71
2.0 > v \ge 1.4 L = -5.0 \times v + 16.0
1.4 > v \ge 1.05 L = -8.57 \times v + 21.0
1.05 > v \ge 0.85 L = -20.0 \times v + 33.0
0.85 > v \ge 0.65 L = -20.0 \times v + 33.0
0.65 > v \ge 0.56 L = -55.56 \times v + 56.11
0.56 > v \ge 0.42 L = -35.71 \times v + 45.0
0.42 > v \ge 0.32 L = -100.0 \times v + 72.0

Arduino sketch

#define ds_pin 0    // Pin to which the distance sensor is connected
#define ds_scaledResolution (5/1024)

#define ds_valueAt50 900     // The value the sensor returns at 50mm distance
#define ds_valueAt200 200    // The value the sensor returns at 200mm distance

int ds_value;          // Integer to hold distance sensor’s reading
float ds_scaledValue;  // Distance sensor’s scaled value
float volt;
float L;

void setup ()
{
  Serial.begin (9600); // Initiates serial communication at 9600 baud
}


float v2l(float v) {
  float l;
  if (v >= 2.0) {
    l = -2.86 * v + 11.71;
  } else if (v >= 1.4) {
    l = -5.0 * v + 16.0;
  } else if (v >= 1.05) {
    l = -8.57 * v + 21.0;
  } else if (v >= 0.85) {
    l = -20.0 * v + 33.0;
  } else if (v >= 0.65) {
    l = -20.0 * v + 33.0;
  } else if (v >= 0.56) {
    l = -55.56 * v + 56.11;
  } else if (v >= 0.42) {
    l = -35.71 * v + 45.0;
  } else if (v >= 0.32) {
    l = -100.0 * v + 72.0;
  } else {
    l = 9999;  // NG
  } 
  return l;
}


void loop ()
{
  ds_value = analogRead (ds_pin);     // Reads the distance sensor
  volt = (ds_value * 5.0) / 1024;
  L = v2l(volt);

 //     Serial.println(volt);
  if (L == 9999) {
    Serial.print("NG!");
  } else {
      Serial.println( L);
  }
  //Serial.println((int) ds_scaledValue);
  delay(500);  // Delay of 500ms
}


05 2月

障害物を見つける


超音波センサーを使って障害物があるか探る。

準備するもの

名前 仕様
マイコン Arduino UNO
超音波センサー Ultrasonic Ranging Module HC-SR04

距離計を使用するためにNewPing Library を使う。

  1. NewPing の Dwonloadサイトから zip ファイルをダウンロード。
  2. zip ファイルを解凍して ~/Documents/Arduino/libraries/ にコピーする。
    $ cp -r NewPing ~/Documents/Arduino/libraries/

    total 8
    drwxr-xr-x  6 sin0414  staff  204 11 16 18:34 NewPing

Arduino IDE での開発

  1. Arduino IDEのメニューから「スケッチ」→「ライブラリを使用」→「Add Library…」で NewPing を追加する。
#include <NewPing.h>

// ---------------------------------------------------------------------------
// Example NewPing library sketch that does a ping about 20 times per second.
// ---------------------------------------------------------------------------

#define TRIGGER_PIN  12  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     11  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.

void setup() {
  Serial.begin(115200); // Open serial monitor at 115200 baud to see ping results.
}

void loop() {
  delay(50);                      // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
  unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS).
  Serial.print(&quot;Ping: &quot;);
  Serial.print(uS / US_ROUNDTRIP_CM); // Convert ping time to distance and print result (0 = outside set distance range, no ping echo)
  Serial.println(&quot;cm&quot;);
}
22 11月

Arduino でモーターを回す


準備するもの

回路図を示す。

arduino_dc-motor-fig1

arduino_dc-motor-fig2

Arduino Code

/*
 * Arduino code for SN754410 H-bridge 
 * motor driver control. 
 * copyleft Feb. 2010, Fabian Winkler
 * 
 */
int speedPin = 3; // H-bridge enable pin for speed control
int motor1APin = 6; // H-bridge leg 1 
int motor2APin = 7; // H-bridge leg 2 
int ledPin = 13; // status LED
int speed_value_motor1; // value for motor speed
void setup() {
 // set digital i/o pins as outputs:
 pinMode(speedPin, OUTPUT);
 pinMode(motor1APin, OUTPUT); 
 pinMode(motor2APin, OUTPUT); 
 pinMode(ledPin, OUTPUT);
}

void loop() {
 digitalWrite(ledPin, HIGH); // status LED is always on

 // put motor in forward motion
 digitalWrite(motor1APin, LOW); // set leg 1 of the H-bridge low
 digitalWrite(motor2APin, HIGH); // set leg 2 of the H-bridge high

 // just invert the above values for reverse motion,
 // i.e. motor1APin = HIGH and motor2APin = LOW 

 // control the speed 0- 255
 speed_value_motor1 = 127; // half speed
 analogWrite(speedPin, speed_value_motor1); // output speed as 
// PWM value
}
23 2月

Node.js with Arduino


  • Draft
  • 作成日:2013年2月23日
  • 作成者:AONO Masayuki<msyaono(at)rockos.co.jp>

本書はArduinoを使ってnode.jsと連携するまでの記録です。

1 導入編

ハードウェア構成

ここでは、Arduinoをネットワークに繋いで照度センサの値をnode.jsアプリに送るために必要な最小構成のハードウェアを準備する。

名称 メーカ(購入先) 数量 単価 備考
ARDUINO Uno R3 Amazon 1 2,520
イーサネットシールド for Arduino (micro SD, Wiznet W5100) Amazon 1 1,700 MacAddr 90-A2-DA-0D-D1-A3
ブレッドボード Amazon 1
Cdsセル、抵抗、ジャンパ線 Amazon 一式
USBケーブル(A-B) Amazon 1

setup&config

  1. Arduino IDEのMac版をダウンロード

  2. ArduinoとMacをUSBケーブルで接続

  3. IDEを立ち上げてツール->シリアルポートから/dev/tty.usbmodemfd121を選択する。

動作確認

LEDブリンクサンプル

  1. ファイル->スケッチの例->01.Basics->Blinkを選択する。
  2. サンプルソースコードがIDE上に表示されるので、コマンドキー⌘+Rでコンパイルする。
  3. ⌘+UでArduinoに書き込む。
  4. バイナリが正常に転送されるとプログラムが走り、LEDが1秒周期でON/OFFする。

Webserverサンプル

  1. ファイル->スケッチの例->Ethernet->WebServerを選択する。
  2. MACアドレスとIPアドレスを書き換える。

    byte mac[] = { 
    0x90, 0xA2, 0xDA, 0x0D, 0xD1, 0xA3 };
    IPAddress ip(192,168,50, 177);
    
    
  3. ⌘+Rでコンパイル、⌘+UでArduinoに書き込む。
  4. 同じセグメントからhttp://192,168.50.177にアクセスすると、アナログ値が表示される。

sample source

/*
  Web Server
 
 A simple web server that shows the value of the analog input pins.
 using an Arduino Wiznet Ethernet shield. 
 
 Circuit:
 * Ethernet shield attached to pins 10, 11, 12, 13
 * Analog inputs attached to pins A0 through A5 (optional)
 
 created 18 Dec 2009
 by David A. Mellis
 modified 9 Apr 2012
 by Tom Igoe
 
 */

#include <SPI.h>
#include <Ethernet.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 
  0x90, 0xA2, 0xDA, 0x0D, 0xD1, 0xA3 };
IPAddress ip(192,168,50, 177);

// Initialize the Ethernet server library
// with the IP address and port you want to use 
// (port 80 is default for HTTP):
EthernetServer server(80);

void setup() {
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}


void loop() {
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    Serial.println("new client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connnection: close");
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
                    // add a meta refresh tag, so the browser pulls again every 5 seconds:
          client.println("<meta http-equiv=\"refresh\" content=\"5\">");
          // output the value of each analog input pin
          for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
            int sensorReading = analogRead(analogChannel);
            client.print("analog input ");
            client.print(analogChannel);
            client.print(" is ");
            client.print(sensorReading);
            client.println("<br />");       
          }
          client.println("</html>");
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } 
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
    Serial.println("client disonnected");
  }
}

Websocketのサンプル

ArduinoにCdsセルを接続し、測定値を生でNode.jsアプリケーションに送信するサンプル。

  1. Githubで公開されているWebsocketclientライブラリ をZipでダウンロードする。
  2. 以下のフォルダーにコピーする。
     # mv ~/Downloads/ArduinoWebsocketClient-master /Applications/Arduino.app/Contents/Resources/Java/libraries/
    
    
  3. ディレクトリ名に’-‘がつくとArduinoIDEにおこられるので、名前を変更する。
    # mv ArduinoWebsocketClient-master Websocket    
    
  4. ArduinoIDEを起動し、スケッチ->ライブラリを使用->Websocketを選択する。

  5. Arduino側はsocketクライアントとしてプログラムを作成する。

    #include "Arduino.h"
    
    #include <WebSocketClient.h>
    #include <SPI.h>
    #include <Ethernet.h>
    
    // Enter a MAC address and IP address for your controller below.
    // The IP address will be dependent on your local network:
    byte mac[] = { 
    0x90, 0xA2, 0xDA, 0x0D, 0xD1, 0xA3 };
    IPAddress ip(192,168,50, 177);
    
    /* socket.io server */
    char SERVER[] = "192.168.0.150";
    byte PORT = 3011;
    WebSocketClient client;
    
    
    // Initialize the Ethernet server library
    // with the IP address and port you want to use 
    
    void setup() {
    
    
      // Open serial communications and wait for port to open:
      Serial.begin(9600);
       while (!Serial) {
        ; // wait for serial port to connect. Needed for Leonardo only
      }
      // start the Ethernet connection and the server:
      Ethernet.begin(mac, ip);
    
      Serial.print("Debug: Setup");
      delay(1000);
    
      if(client.connect(SERVER, "/socket.io/1/websocket/", 3011)){
        client.setDataArrivedDelegate(dataArrived);
        delay(1000);
      } else { 
        while(1){}
      }
    
    }
    
    void dataArrived(WebSocketClient client, String data) {
      Serial.println("Data Arrived: "+data);
    }
    
    /*
     * main loop
     */
    void loop() {
    
      client.monitor();
      /* Read value of Cds cell*/
      int sensorReading = analogRead(0);
    
      /* send a message */
      String message = "{";
      message += "\"CDS_A0\":";
      message += sensorReading;
      message += "}";
    
      client.send(message);
      delay(1000);
    }
    
    
  6. Node.jsで動くSocketサーバのプログラムを以下に示す。
    var HOST = '127.0.0.1';
    var PORT = 3011;
    
    function log(objs) {
        var d = new Date,
            fmtDate = '',
            month;
        var msg = {};
        month = d.getMonth() + 1;
    
        fmtDate = d.getFullYear() + '/' + month + '/' +     d.getDate() +
            ' ' + d.getHours() + ':' + d.getMinutes() + ':' +
            d.getSeconds() + ':' + d.getMilliseconds();
    
        console.log(fmtDate + ' ' + objs.title+':'+objs.info);
    }
    /**
     *
     */
    var ws = require('websocket.io').listen(PORT);
    
    ws.on('connection', function(socket){
        log({'title':'socket','info':'bound on '+PORT});
        socket.on('message', function(data){
            log({'title':'socket','info':data});
        });
    });
    
  7. arduinoを起動した時のServer側のログ
    $ node unosrv
    $ node websocksrv.js 
    2013/2/26 11:37:5:890 socket:bound on 3011
    2013/2/26 11:37:7:7 socket:{"CDS_A0":626}
    2013/2/26 11:37:8:9 socket:{"CDS_A0":626}
    2013/2/26 11:37:9:16 socket:{"CDS_A0":625}
    2013/2/26 11:37:10:17 socket:{"CDS_A0":626}
    2013/2/26 11:37:11:22 socket:{"CDS_A0":625}