Arduinoの最近のブログ記事

Arduinoでサーボ制御

夏休みに工業系先生向けの制御講習会を行うけど、 例年参加している人もでてくるので、少しは違う実験とすべく、 サーボモータの制御を入れてみようと計画中。 ということで、手持ちである共立電子の通信販売のサーボモータ(プチロボ)を動かしてみた。

#include <Servo.h>

Servo motor ;    // White D9
int   d = 1 ;    // Red   5V
int   v = 0 ;    // Black GND

void setup() {
  motor.attach( 9 ) ;
}

void loop() { // 0°〜180°〜0°を繰り返す。
  motor.write( v ) ;
  v = v + d ;
  if ( v >= 180 ) {
    v = 179 ;
    d = -1 ;
  } else if ( v < 0 ) {
    v = 0 ;
    d = 1 ;
  }
  delay( 2 ) ;
}

これで動かすと、このサーボモータでは、プログラム的には0-180で変化させているが、実際の変化幅は120°程であった。 delay(1)にすると、サーボの制御信号の変化にモータが追いつけないため、 90°ほどの変化幅となった。

ちなみに、最近購入したArduino Uno であったが、開発環境は Arduino 0022 に 更新しないと、Uno への書き込みができなかった。(0017はダメ)

加速度センサーと連動

加速度センサーで傾きを検出し、傾きに応じてサーボモータを動かしてみた。

#include <Servo.h>

Servo motor ;

int acc_x ;  // Vcc--3.3V, GS1-GND g1.5
int acc_y ;  // GND--GND , GS2-GND
int acc_z ;  // X----AN0 , SLP-3.3V
int ang ;    // Y----AN1
             // Z----AN2
#define OFFSET 335
void setup() {
  motor.attach( 9 ) ;
  acc_x = acc_y = acc_z = 0 ;
}
void loop() {
  acc_x = (3*acc_x + analogRead(0) - OFFSET )/4 ; // 加重移動平均
  acc_y = (3*acc_y + analogRead(1) - OFFSET )/4 ;
  acc_z = (3*acc_z + analogRead(2) - OFFSET )/4 ;
  
  ang = (int)( atan2( acc_y , acc_x ) / 3.141592 * 180 ) ;
  ang = constrain( ang , 0 , 180 ) ;
  delay( 2 ) ;
}

この記事は、twitter の @TohruSaitohに掲載した #fnct タグ付き記事を、まとめたものです。


創造工学演習でハードウェア系を作るネタの導入として、 Ethernet シールド付き Arduino を動かしてみた。単なるメモなので...

// 雛形のスケッチは、
// ..PATH../Arduino.app/Contents/Resources/Java
//    /hardware/libraries/Ethernet/examples/WebServer/WebServer.pde
#include <ethernet.h>

byte mac[]	= { 0x02 , 0x11 , 0x22 , 0x33 , 0x44 , 0x55 } ;
byte ip[]	= { 192 , 168 , 2 , 88 } ;  //
byte gateway[]	= { 192 , 168 , 2 ,  1 } ;  // 
byte subnet[]	= { 255 , 255 , 255 , 0 } ; // Class-C

Server server = Server( 80 ) ;

void setup() {
  Ethernet.begin( mac , ip , gateway , subnet ) ;
  server.begin() ;
  Serial.begin( 9600 ) ; // 動作確認用に受信データを表示
}

void loop() {
  Client client = server.available() ;
  if ( client ) {
    // an http request ends with a blank line
    boolean current_line_is_blank = true;
    while( client.connected() ) {
      if ( client.available() ) {
        char c = client.read();
	
	Serial.write( c ) ; // 動作確認用に、受信データを表示

        // if we've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so we can send a reply
        if ( c == '\n' && current_line_is_blank ) {
          // send a standard http response header
          client.println( "HTTP/1.1 200 OK" ) ;
          client.println( "Content-Type: text/html" ) ;
          client.println();
          
          // output the value of each analog input pin
          for (int i = 0; i < 6; i++) {
            client.print("analog input ");
            client.print(i);
            client.print(" is ");
            client.print(analogRead(i));
            client.println("<br />");
          }
          break;
        }
        if (c == '\n') {
          // we're starting a new line
          current_line_is_blank = true;
        } else if (c != '\r') {
          // we've gotten a character on the current line
          current_line_is_blank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    client.stop();
  }
}

上記プログラムを検証&書き込みの後、ブラウザで http://192.168.2.88/ にてアクセスする。すると、シリアルモニタには下記の出力が得られた。 後半は、ブラウザがfavicon.icoを取得しようとしたアクセスが行われている。 しかし上記のプログラムは、何をGETしようとしたのか判別せずに、リクエスト末尾の 『空行』を見つけたら、アナログ値を出力しようとするだけ。 このため、Reload する度に、2回アナログ値サンプリングが行われる。

GET / HTTP/1.1
Host: 192.168.2.88
Connection: keep-alive
User-Agent: Mozilla/5.0 ...Safari/532.5
Cache-Control: max-age=0
Accept: application/xml,application/xhtml+xml,text/html;...
Accept-Encoding: gzip,deflate,sdch
Accept-Language: ja,en-US;q=0.8,en;q=0.6
Accept-Charset: UTF-8,*;q=0.5

GET /favicon.ico HTTP/1.1
Host: 192.168.2.88
Connection: keep-alive
User-Agent: Mozilla/5.0 ...Safari/532.5
Accept: */*
Accept-Encoding: gzip,deflate,sdch
Accept-Language: ja,en-US;q=0.8,en;q=0.6
Accept-Charset: UTF-8,*;q=0.5

ブラウザで、http://192.168.2.88/ で表示された結果は、下記の通り。 ちなみにアナログポートは、実験だし開放のまんまで、ゴミデータ。

analog input 0 is 393
analog input 1 is 331
analog input 2 is 282
analog input 3 is 286
analog input 4 is 269
analog input 5 is 284

Arduinoのloop()の外

卒研テーマにArduino+Ethernetシールドで何か作れないかと、個人的&指導的に Arduinoの中身を確認中。

Arduinoって、setup()とloop()を書けば動き出すんだけど、 Ethernetシールドのサンプルプログラムで、setup()の中に 様々な処理が書いてある。確認する前は、main()って、以下のような物だと思ってた。

int main() {
   ArduinoのCPUの違いに応じたinit() ;
   init() ;
   ArduinoのCPUの違いに応じたsetup() ;
   setup() ;
   for(;;) {
      周辺IO関連関数に伴なう処理() ;
      loop() ;
   }
   return 0 ;
}

みたいなもんだと思ってた。だから setup() の中身に、何でも処理を書くと、 IOに絡む関数で動かなくなるものが出てくるだろう...と思っていたが、 /PATH/java/hardware/core/arduino/main.cxx を見ると、 順次必要な処理が並んでいるだけ。

int main( void ) {
   init() ;
   setup() ;
   for(;;)
      loop() ;
   return 0 ;
}

これなら、IO系のシールドのライブラリ書く人は大変かもしれんが、 訳の分からない処理の制約はないな...

Arduino講習会

| コメント(1)

福井の情報系技術者の方や学生さんを交えた、Arduinoを使った講習会が ありました。主催や講師は電子情報のOBの方々で、 学生さんからの視点とは違った質問もあって、説明することの難しさを改めて実感。

0909050955_320x240.jpg
LEDの抵抗って...
LEDを光らせる際の保護抵抗の算出方法の説明中に、LEDの抵抗値の質問がでる。 等価回路として抵抗と電源で表現して説明しようとしたけど、 直感的に解ってもらえる説明って難しい。
VCCって何の略?
そういえば、何だろう。 VCEであれば、コレクタ-エミッタ間電圧とかだけど、C-Cって何やねん... C-MOSだったりすれば、VSS,VDDで、接続される先がコレクタ・ソース・ドレインってのは解る。なんで2文字でだぶらせるのか.... VA,VB,VCじゃあ、特定の素子両端の電圧っぽいし、区別するためと思うんだが...ずばり○○だからという説明の記事が見つからない...

2015年12月

    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    

アーカイブ

Google

このアーカイブについて

このページには、過去に書かれたブログ記事のうちArduinoカテゴリに属しているものが含まれています。

次のカテゴリはH8です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。