ユーザー作ったりとか

投稿日:

 Raspberry Piで遊ぶ。

 私が買ったのは、「Raspberry Pi 2 Model B」という最新のものだ。オライリー・Make:PROJECTSシリーズの「Raspberry Piをはじめよう」で解説されているのは古い方の「Raspberry Pi モデルA」「同B」なので、少しづつ合わないところがあるが、ごく細部を除いては、特に気にする必要はない。細部の違いが影響してくるのは、よほど高度なことをやる場合だ。

 今さら私が述べ立てることではないと思うが、私と同じような人で、Rasberry Piのことを知らない、という人に向けて書けば、結局はこうだ。

  •  Raspberry Piは、GPIOインターフェイスボードを積んだ普通のPCだと思えばよい。
  •  普通のPCなので、Linux系OS以外にも、Windows10なども使える。だが、成果物のほとんどはRaspbianというLinuxディストリビューション上で得られているので、OSにはRaspbianを選択しておくのが無難。
  •  前記GPIOは、普通にファイルに見えるので(と言っても、/devの下にデバイスファイルがあるわけではない;もちろん、シンボリックリンクでそういうふうにすることはできるが)、標準出力でファイルを開け、書いて閉じれば、それでGPIOにつないだ電子工作をコントロールできる。
  •  Arduinoに比べると、ロジックが正=3.3Vであること、アナログ入力がないことなどが違う。解説書「Raspberry Piをはじめよう」にも、
    「最初にRaspberry Piのニュースが流れたとき、それがArduinoキラーになるのではないかと多くの人が考えました。値段はたいして違わないのに、Piはずっと大きなCPUパワーを持っています。だったらArduinoを使う理由はもうない、というわけです。しかし、やがて両者は補完的な関係にあることが分かってきました。以下のような状況を考えると、ArduinoとPiを組み合わせるメリットが見えてきます。

    • Arduinoの豊富なライブラリと作例を活用したい。
    • すでにうまく動いているArduinoプロジェクトにCPUパワーを追加して、もっと高度なことがしたい。
    • 5Vで動作する回路を扱いたいが、Piは3.3V動作で、5V入力に対応しない。
    • 誰かがプロトタイピングの過程で少しばかり無茶をしてチップがダメージを受けた時(Arduinoのピンにモーターを直結している人を見たことがあります)、Arduinoならば数百円以下でスペアのチップを買って自分で交換することもできるが、Piでそれをするのはほぼ不可能。
    •  3Dプリンタ用コントローラのように高精度なリアルタイム処理を必要とするものを作るとき、リアルタイムOSとは言えないRaspbianよりも、命令サイクルを計算できるマイクロコントローラのほうが要求に適う可能性が高い

    (p.88冒頭から引用)
    ……等とある。

  •  Linuxなので、使い始めるにはとりあえずrootを把握して、ユーザを作ればよい。作りつけのユーザもあるが、私のようなおっさんは、まず
    「# useradd -g pi toshio ; passwd toshio ; mkdir /home/toshio ; chown toshio:pi /home/toshio」
    ……なんてことをやらないと落ち着かないのである。
  •  さまざまな作例等はPythonの利用が想定されているので、さまざまな作品例のマネがしたければPythonを使えばよいが、前記したように「普通のLinuxマシン」なので、PerlだろうがCだろうが、おっさん系の言語も全部使えるから、私のようなおっさんは自分が使いたい言語を使えばよい。

 なので、例えば、「Raspberr Piをはじめよう」の102ページあたりに載っている最初のLチカの例は、次のような方法でも再現できる。

#!/usr/bin/perl
#  perl2LED
#    perlでLチカ
#    27.8.16(日)
#    佐藤俊夫
#
open(GPIO25, ">/sys/class/gpio/gpio25/value");
GPIO25->autoflush(1);
while(){
  print GPIO25 1;
  sleep(1);
  print GPIO25 0;
  sleep(1);
}

……などとPerlで書き、「gpio25」をユーザ空間にエクスポートして、

# ./perl2LED

 とやると、LEDが1秒おきにチカチカするのである。

Raspberry PiでのLチカ最初の例
IMG_3285

その意味を

投稿日:

 終戦記念日には靖国神社へ参拝に行っている。最近──とは言っても、十数年来くらい──の習慣だ。

 その範囲で最も混雑したのは、たしか、大震災の前、民主党政権に代わって1年ほど経った後の、平成22年の8月であったと記憶する。この時には、地下鉄九段下の駅の中まで行列が続いていた。

 あの頃を振り返ると、当時実際の多くの人々の行動はマスコミの論調とは全く逆方向に志向し、精神が沸騰していたのを、生の現場ではひしひしと感じ取れたものであった。だが、あの年、例年より混雑する靖国神社周辺の様子はほとんど報道されることなく、むしろ「靖国神社なんぞに参拝するような変な日本人のことを全アジア諸国の皆さんが残念がり、ないしは激怒しており、靖国神社は低迷している」みたいな報道ぶりだった。

 去年は終戦記念日に仕事をしていたので、仕事が終わってから夕刻に参拝したが、今年は休みなので、朝から出かけた。

 私の家からは、電車1本で直接九段下へ行ける。そうして午前10時半頃に九段下の駅に着いてみて、さあ、今日と言う今日は驚いた。

 九段下の駅構内こそ人が流れてはいたが、地上へ出てみてびっくりである。九段下の駅の入り口は東西にあり、靖国神社側と九段下交差点側があるのだが、大鳥居の入り口にほど近い西側の駅入り口から九段下の交差点まで、延々と人が並んでいるではないか。しかも、単にワン・パスで並んでいるのではない、九段下駅西側入り口から九段下交差点まで反対向きに並び、列はそこから折り返して靖国神社へ向かっているのである。

 こんなことは初めてである。人員整理の仕方を少し変えていたということもあったようだが、それにしても大変な人出だ。

 数字を確かめていないので正確なところはわからないが、あの平成22年の8月よりもまだなお混雑しているように感じられた。

 靖国神社は自分の政治的思想を開陳する場とは違う。英霊へ鎮魂の祈りと誠をささげまつる場である。それを、がなり立てる右翼はまだしも、着用する資格のない軍服など一着に及んで、なにやらコスプレ祭りと勘違いしている若者も出てくる始末で、毎年毎年嘆かわしいことだが、愛の反対は無関心、ということからすれば、それもむべなるかな、とは思う。

 この世情下、これほど多くの人が参拝に来ているわけを、この混雑、その意味を、自分なりに考えてみたい。

 この膨大な人数の参拝客は、あの戦争とそれに参加し死んだ人々を、もう一度評価しなおしたいと考えているように見える。たとえ悪い方向へ批判するのであっても、逆に良い方向へ評価するというのであっても、どちらでも良いから冷静に何かを問いたい、そのための元となる行動を何かしないと、そういう行動をとらないと、もう、議論をただの一歩も先へ進めることが出来ない、何もしないでは議論を深める資格がない、そう考えているのではないだろうか。

 そうすると、靖国の境内を例年の倍にも感じられるほど埋め尽くす人々の姿は、英霊に仮託した自己の求道の姿だということになる。

 そうであるならば、それは政治的なパフォーマンスに近く、英霊の鎮魂のための行為ではない。とても神社ですることとは言えないが、しかし、護国の鬼たちは今や柔和にそれを許し給うと考えたい。

11892024_1008516605845859_6741406045379287350_n

 2時間ほどは並ぶ始末であった。中門鳥居のあたりで正午を迎えることとなったため、千鳥ヶ淵から中継でスピーカー放送されてくる慰霊式の様子に聴き入った。国歌斉唱のおり、靖国神社境内の群衆が誰ともなく歌い始めるのも例年と同じだ。はじめは遠慮がち、恥ずかしげに小さい声で口ずさんでいた人々の歌声が次第に大きな声になっていく。こうべを垂れて天皇陛下のお言葉を謹聴する。ちょうど正午、帽子を脱して黙祷する。

 ともあれ、英霊やすらかにしずみたまえ、と参拝はそれのみ考えつつ済ませ、帰路、あれこれと考えに耽った。

 靖国通りを神田に向かって歩いていたら「藪仙」という蕎麦屋があったので、ひょいと入る。大蒸篭せいろを頼んだら3枚もついてきて、お得。酒を2合。

 せっかく神田あたりに来たなら、蕎麦は名代の「まつや」に寄りたいところだが、籔仙の大蒸篭を手繰り終わってからまつやの前を通りかかると、案の定、炎天下数十人の行列だった。まつや目当てに連雀町へ来て見ても、これではとても並ぼうという気は起きなかったろう。多分今日は例年通り「神田・籔」が盆休みで、その客もまつやが吸収しているものと見える。

 暑かったが秋葉原まで歩いた。九段下から秋葉原までは歩いて30~40分だ。千石電商でフラックスとソルダーウィック、蛇の目基盤を買う。ヨドバシへ行ってHDMIとDVI-Dの変換アダプタをひとつ買う。これはRaspberry Piを今使っているPCのモニタにつなぐため。

 秋葉原のメイド通りは、今日が終戦記念日だということなどまるで知らぬげに、世界各国の老若男女とメイドでごった返していた。

今10分ほどRaspberry Piを触ってみて分かったのは、

投稿日:

 今10分ほどRaspberry Piを触ってみて分かったのは、Raspberry Piは結局のところ、Linuxでの使用が基本なので、私のようにUNIX育ちの人物には、かえってとっつきやすく扱いやすい、ということだ。

 これはいい。

 Windows10はRaspberry Piのサポートも表明しているやに聞くが、Windowsでハードウェアに触ろうなんて気持ち、まったく起きないもんなあ……。

買っちゃった

投稿日:

 前々からいじってみたいと思っていたものの一つがArduinoであった。これはもう、だいぶ前から触ってみたかった。人様より遅れ馳せながら、この春からいじりはじめることができ、楽しく過ごすことができた。

 触ってみたかった物の二つめが、「Raspberry Pi」である。

 まずArduinoがだいたいいじれるようになって、それからおもむろにRaspberry Piに行ってみよう、と考えた。この春以降頃からのArduinoのほうの進捗から言って、Raspberry Piがいじり始められるのは夏頃にはなるかな、と予測した。

 Arduinoはたぶんなかなか上達しないだろうと踏んでいたが、思いのほか、最近は思ったことがだいたいできるようになった。

 それで、最初のもくろみ通り、盆休みにははじめにRaspberry Piを買って、休みの間いじり倒してみよう、と思っていたのだが、意外にArduinoのほうで、これもやってみようあれもやってみようと、やりたいことが次々にあるものだから、休暇も終わり近くなってからやっとRaspberry Piに目が向いた。

 昨日、秋葉原へ行って、買っちゃった。小遣いがあるうちに、買っちゃえ買っちゃえ(笑)。

IMG_3277
IMG_3278
IMG_3279
IMG_3280
IMG_3282
IMG_3284

ネット便器

投稿日:

 時代はIoTである。モノをネットに接続することは、もはや正義を通り越して神の啓示であるとすら言えるほどだ(笑)。

 やろうやろうと思ってやっていない一事はこのことだ。すなわち、「Arduino」を使用して、直接モノにツイートさせること、これである。モノがツイートするのはきっと面白いに違いない。

 「Twitter Arduino」あたりで検索すると、ライブラリが出てくる。今回はこれ(Tweet Library 1.3)をありがたく使わせていただく。

 さて、そうと決まれば何をネットに接続するか、である。ここはやはり、自宅の便器をネットに接続するという、これを一度やってみるべきであろう。

 やはり、IoT時代であるから、便器もネットにつないでやらなければ面白くないだろう。便器だって平等に扱ってやらねば、他の物品との差別感を覚えてひがむようになり、性格が曲がってしまうかもしれない。このように性格の歪んだ便器は、人間様が用を足すときに局部に噛みついてくるようなことが万に一つはないとも限らない。便器にも時々はインターネットと会話をさせてやるべきだ。

 とりあえず、便所のフタの開閉を検知するため、「チルトスイッチ」を使用する。

チルトスイッチ
IMG_3218

 これは、傾けるとスイッチが入るというもので、Arduinoを買ったときに一緒に買った「Seeedstudio SIDEKICK BASIC KIT」というセットに入っていたものだ。

 回路は簡単である。下図のように、行儀よく10kΩほどプルダウンしておけば誤動作は少ない。

チルトスイッチ回路図

 スケッチのほうは、ライブラリの導入に多少手間取った。使用させていただいた「Tweet Library」は、「ETHERNET SHIELD」のほうに対応しており、私が持っている「ETHERNET SHIELD 2」にはそのままでは対応していない。

 基本的にヘッダファイルのインクルードを「#include <Ethernet.h>」から「#include <Ethernet2.h>」に書き換えるだけでいいのでは、と思ったのだが、どうもうまくいかない。さっぱりお手上げだったのだが、いろいろといじくりまわしているうち、エラーメッセージをよく見てみると、「クラスの2重定義」という意味のエラーが出ていることがわかった。なぜか、「libraries\Ethernet2\srcの下にあるやつと重なっている」みたいなメッセージが出ている。ハテ、とライブラリのあるディレクトリを見てみると、「libraries\Ethernet2\src」の下に、なぜか「Twitter.h」と「Twitter.cpp」がある。

 なんだかわかんないけどいいや、消しちゃえ!と、それをぞんざい適当に消したら、うまくコンパイルできるようになった。しかし、そのことで5~6時間ほどハマッてしまった。

 ETHERNET SHIELD 2とプロトタイプシールドを、先日買った「継ぎ足しピンヘッダ」を介して積み重ね、次のようにしていつもの100円ショップのアクリル枠にねじ止めする。

IMG_3213

 手前に緑色のチルトスイッチが取り付けられていることがわかるだろう。

 Twitterに専用アカウントをとり、Tweet Libraryの説明にしたがってトークンを取得する。専用アカウントは、その名も「佐藤家の物」である(笑)。

 それから、スケッチを次のように書く。

//
//  つぶやき便所 tweetToilet.ino
//    27.08.08(土) 1000~
//    佐藤俊夫
//    チルトスイッチで便所のふたの動きを検出し、呟かせる。
//
#include <SPI.h>
#include <Ethernet2.h>
#include <Twitter.h>
#include <stdio.h>
//
byte MAC[] = { 0x90, 0xA2, 0xDA, 0x0F, 0xF6, 0x74 };
IPAddress IP(192, 168, 1, 129);
Twitter TWITTER("hogehogehoge-hagehagehagehage......");  //  トークン
const int TILTSW = 9;
//
void setup()
{
  pinMode(TILTSW, INPUT);
  delay(1000);
  Ethernet.begin(MAC, IP);
  delay(1000);
}

void loop()
{
  static int tiltSwStatus = LOW, prevStatus = LOW;
  int i = 0;
  tiltSwStatus = tiltSw();
  if(tiltSwStatus != prevStatus){
    prevStatus = tiltSwStatus;
    tweetMsg(tiltSwStatus);
    delay(1000);
  }else{
    ;
  }
}
//
int tiltSw(){
  //  チルトスイッチの読み取りを安定させるため、100回連続して同じ値が返るまで読む。
  int i = 0, prevStatus = LOW, nowStatus = LOW;
  prevStatus = digitalRead(TILTSW);
  do{
    nowStatus = digitalRead(TILTSW);
    if(nowStatus == prevStatus){
      i ++;
    }else{
      i = 0;
    }
    prevStatus = nowStatus;
  }while(i < 100);
  return(nowStatus);
}
//
void tweetMsg(int tiltStatus){
  const char
    openMsg[] = "%e3%82%84%e3%81%82%e3%80%82%e4%bf%ba%e3%81%af%e4%bd%90%e8%97%a4%e5%ae%85%e3%81%ae%e4%be%bf%e5%99%a8%e3%81%a0%e3%80%82%e4%bb%8a%e3%83%95%e3%82%bf%e3%81%8c%e9%96%8b%e3%81%84%e3%81%a6%e3%81%84%e3%82%8b%e3%80%82",
    //  'やあ。俺は佐藤宅の便器だ。今フタが開いている。'    
    closeMsg[] = "%e4%bf%ba%e3%81%af%e4%bd%90%e8%97%a4%e5%ae%85%e3%81%ae%e4%be%bf%e5%99%a8%e3%81%a0%e3%80%82%e4%bb%8a%e3%83%95%e3%82%bf%e3%81%8c%e9%96%89%e3%81%be%e3%81%a3%e3%81%9f%e3%80%82";
    //  '俺は佐藤宅の便器だ。今フタが閉まった。'
  char tweetStr[256];
  if(tiltStatus == HIGH){
    sprintf(tweetStr, "%s  \r\n %ld", openMsg, millis());
    //  Twitterは同じ文字列を繰り返し書き続けられないので、起動時間を付けて書き、重複を防ぐ。
  }else{
    sprintf(tweetStr, "%s  \r\n %ld", closeMsg,  millis());
  }
  TWITTER.post(tweetStr);
  TWITTER.wait();
}

 うまく動くようになったら、ホット・グルーでプロトタイプを便器のフタに取り付ける。

IMG_3216IMG_3215

 便所にLAN工事を施しておしまいだ。

IMG_3214
 

 上記動画のように便器のふたを開け閉めすると、やおら便器が次のように呟きだすのである。



空の写真リベンジ

投稿日:

 先週試したAdafruit製の「小型TTLシリアルjpegカメラ」での間欠撮影先週はどうしたわけか同じ画像ばかり撮れてしまい、失敗である。

 (チナミに、このカメラのメーカーの「Adafruit」という会社、有名なマッシモ・バンジのTEDの中で紹介されていたことに気付いた。)

https://youtube.com/watch?v=UoBUXOOdLXY%3Ft%3D5m50s

 気を取り直して、スケッチを直す。撮影時のカメラのステータスを確認し、撮れていなければ何回でも撮り続ける。

「while(撮れてない)撮る;」

……というわけだ。まあ、万が一ハードウェアエラーなどがあるとループが回り続けるので良くないが、ループが回り続けようが結局のところはモノとしては電源を入れ直す他にどうしようもないので、こんなものだろう。

 それと、撮影が終わったらカメラをそのつどリセットすることにした。また、既に存在するファイル名は避けるようにした。こういう時、Arduinoには書式文字列付きの「sprintf」がないので、少し不便だなと思う。

 夜明けから日没までの一日の空の雲を撮りたいので、天気予報を見て雨が降らぬ確信を持ってから、昨夜寝る前にベランダにカメラをセットしておいた。朝早く起きるより楽だからだ。夜のうちに1000枚くらい写真が撮れてしまうが、SDカードには余裕があるので大丈夫である。

 昼間は用事があるのでカメラの面倒は見れないが、放置しておけば淡々と写真は撮れていく。

IMG_3143

 で、撮れた写真をWindows Movie Makerに流し込むと、微速撮影動画の一丁上がりだ。

 スケッチは次のとおりである。

//
//  camera2Web.ino
//    27.07.20(月) 0850~
//    佐藤俊夫
//    Adafruit製小型TTLシリアルJPEGカメラ+ETHERNET SHIELD 2で
//    間欠撮影をし、Webでダウンロードできるようにする。
//
#include <Adafruit_VC0706.h>
#include <SPI.h>
#include <SD.h>
#include <SoftwareSerial.h>
#include <Ethernet2.h>

#define CHIPSELECT 4

SoftwareSerial CAMCONNECTION(2, 3);
Adafruit_VC0706 CAM = Adafruit_VC0706(&CAMCONNECTION);
const unsigned long int INTERVAL = 30L * 1000L;
byte MAC[] = {  0x90, 0xA2, 0xDA, 0x0F, 0xF6, 0x74 };
IPAddress IP(192, 168, 1, 129);
EthernetServer SERVER(80);
EthernetClient CLIENT;

void setup() {
  pinMode(10, OUTPUT);
  if(!SD.begin(CHIPSELECT)) return;
  if(!CAM.begin()) return;
  CAM.setImageSize(VC0706_320x240);
  Ethernet.begin(MAC, IP);
  SERVER.begin();
  delay(1000);
}

void loop() {
  static unsigned long int prevtime = 0;
  char c;
  String rstr = "";
  //  INTERVALおきに写真を撮る
  if(millis() >= prevtime + INTERVAL){
    prevtime = millis();
    takePicture();
  }
  //  Webサーバ
  CLIENT = SERVER.available();
  if(CLIENT) {
    while(CLIENT.connected()) {
      if(CLIENT.available()) {
        c = CLIENT.read();
        rstr += c;
        if(rstr.endsWith("\r\n")){
          break;
        }
      }
    }
    if(rstr.indexOf("IMG") >= 0){
      String filename = "DCIM/";
      char cfilename[17];
      filename.concat(rstr.substring(rstr.indexOf("IMG"), rstr.indexOf("JPG") + 3));
      filename.toCharArray(cfilename, 17);
      CLIENT.println("HTTP/1.1 200 OK");
      CLIENT.println("Content-Type: image/jpg");
      CLIENT.println("Connection: close");
      CLIENT.println();
      File img = SD.open(cfilename);
      while(img.available()){
        CLIENT.write(img.read());
      }
      img.close();
    }else{
      sendform();
    }
    rstr = "";
    delay(1);
    // close the connection:
    CLIENT.stop();
  }
  delay(20);
}

void sendform(){
  //  フォームを送る。
  CLIENT.println("HTTP/1.1 200 OK");
  CLIENT.println("Content-Type: text/html");
  CLIENT.println("Connection: close");
  CLIENT.println();
  CLIENT.println("<!DOCTYPE HTML>");
  CLIENT.println("<html><head></head><body><center>");
  File dcim = SD.open("/DCIM");
  while(true) {
    File imgfile =  dcim.openNextFile();
    if(!imgfile){
      dcim.rewindDirectory();
      break;
    }
    CLIENT.write("<a href=\"");
    CLIENT.write(imgfile.name());
    CLIENT.write("\">");    
    CLIENT.write(imgfile.name());
    CLIENT.println("</a><br>");
    imgfile.close();    
  }
  dcim.close();
  CLIENT.println("</center></body></html>");
}

void takePicture(){
  static unsigned int pnum = 0;
  char filename[] = "DCIM/img0000.jpg";
  while(!CAM.takePicture());
  do{
    filename[8]  = '0' + pnum / 1000;
    filename[9]  = '0' + (pnum / 100) % 10;
    filename[10] = '0' + (pnum /  10) % 10;
    filename[11] = '0' + pnum % 10;
    pnum ++;
  }while(SD.exists(filename));
  if(pnum > 9999) pnum = 0;
  File imgFile = SD.open(filename, FILE_WRITE);
  uint16_t jpglen = CAM.frameLength();
  pinMode(8, OUTPUT);
  while (jpglen > 0) {
    uint8_t *buffer;
    uint8_t bytesToRead = min(32, jpglen);
    buffer = CAM.readPicture(bytesToRead);
    imgFile.write(buffer, bytesToRead);
    jpglen -= bytesToRead;
  }
  while(!CAM.reset());
  imgFile.close();
}




カメラで遊んでみる

投稿日:

 秋月電子のサイトを見ていると、小さなカメラがあり、Arduinoに付きそうな感じだ。

 3850円。Arduino自体が2800円かそこらなので、それに比べるとちょっと高いが、早速行って購入。

 だが、あまり情報は多くない。まず、メーカーのサイトを見ていくと、チュートリアルがあり、「とりあえずテストするには、電源をくれてやって、一番端のピンをテレビにつなぎゃあ絵が出る」みたいなザックリ感満載の解説が。それで、テレビにつなぐためのRCAジャックなども買う。

 チュートリアルはこれを読んでおけばだいたいいいようだ。

 ほどいてみるとこんな感じで、かなり小さい。

IMG_3112

 ピンのピッチが2mmで、ブレッドボードで扱いにくい。それで、普通の2.54mmのピンヘッダを出して、その根元をこんなふうにムリヤリ(笑)2mmピッチにせばめる。

IMG_3116

 こいつをカメラの基盤にえいやっ、とねじ込み、半田付けする。

IMG_3118

 なかなか小さいので、ルーペと老眼鏡を併用しつつ、ICなんか壊しちゃってもナンだから、20Wのぬるくて細い半田鏝でさっさとつける。

IMG_3117

 我ながらなかなかスピーディな仕事だなあ(笑)。

 で、メーカーのサイトには「5V」と書いてあるが、これは互換品の別の製品のためのチュートリアルのようで、買ってきたものの基盤をよく見ると「3.3V」と印刷されている。壊してはもったいないから、3.3Vで試す。3.3Vの電源代わりにArduinoの3.3Vピンを使う。

 基盤の印刷通り、3.3V、GND、それから右端のピンをRCAジャックのセンターに、RCAジャックのアースを同じくGNDに入れて、テレビの前に持っていく。

IMG_3119

 テレビにつなぐと、おお、確かに、値段なりのフザけた画質(笑)で、自分の顔が映る。

IMG_3121

 上下が逆だが、まあ、いいや。

 で、今度はArduinoで画像を撮影してみよう。

 チュートリアルにしたがってArduino用のライブラリをダウンロードし、これをArduinoのインストールフォルダの「libraries」に配置する。

 そうしておいてArduinoのIDEを起動すると、「ファイル」→「スケッチの例」の中に「Adafruit VC0706 Serial Camera Library」が現れるから、この中から「Snapshot」を選ぶ。これは静止画をjpegで撮影するスケッチのサンプルだ。

// This is a basic snapshot sketch using the VC0706 library.
// On start, the Arduino will find the camera and SD card and
// then snap a photo, saving it to the SD card.
// Public domain.

// If using an Arduino Mega (1280, 2560 or ADK) in conjunction
// with an SD card shield designed for conventional Arduinos
// (Uno, etc.), it's necessary to edit the library file:
//   libraries/SD/utility/Sd2Card.h
// Look for this line:
//   #define MEGA_SOFT_SPI 0
// change to:
//   #define MEGA_SOFT_SPI 1
// This is NOT required if using an SD card breakout interfaced
// directly to the SPI bus of the Mega (pins 50-53), or if using
// a non-Mega, Uno-style board.

#include <Adafruit_VC0706.h>
#include <SPI.h>
#include <SD.h>

// comment out this line if using Arduino V23 or earlier
#include <SoftwareSerial.h>         

// uncomment this line if using Arduino V23 or earlier
// #include <NewSoftSerial.h>       

// SD card chip select line varies among boards/shields:
// Adafruit SD shields and modules: pin 10
// Arduino Ethernet shield: pin 4
// Sparkfun SD shield: pin 8
// Arduino Mega w/hardware SPI: pin 53
// Teensy 2.0: pin 0
// Teensy++ 2.0: pin 20
#define chipSelect 10

// Pins for camera connection are configurable.
// With the Arduino Uno, etc., most pins can be used, except for
// those already in use for the SD card (10 through 13 plus
// chipSelect, if other than pin 10).
// With the Arduino Mega, the choices are a bit more involved:
// 1) You can still use SoftwareSerial and connect the camera to
//    a variety of pins...BUT the selection is limited.  The TX
//    pin from the camera (RX on the Arduino, and the first
//    argument to SoftwareSerial()) MUST be one of: 62, 63, 64,
//    65, 66, 67, 68, or 69.  If MEGA_SOFT_SPI is set (and using
//    a conventional Arduino SD shield), pins 50, 51, 52 and 53
//    are also available.  The RX pin from the camera (TX on
//    Arduino, second argument to SoftwareSerial()) can be any
//    pin, again excepting those used by the SD card.
// 2) You can use any of the additional three hardware UARTs on
//    the Mega board (labeled as RX1/TX1, RX2/TX2, RX3,TX3),
//    but must specifically use the two pins defined by that
//    UART; they are not configurable.  In this case, pass the
//    desired Serial object (rather than a SoftwareSerial
//    object) to the VC0706 constructor.

// Using SoftwareSerial (Arduino 1.0+) or NewSoftSerial (Arduino 0023 & prior):
#if ARDUINO >= 100
// On Uno: camera TX connected to pin 2, camera RX to pin 3:
SoftwareSerial cameraconnection = SoftwareSerial(2, 3);
// On Mega: camera TX connected to pin 69 (A15), camera RX to pin 3:
//SoftwareSerial cameraconnection = SoftwareSerial(69, 3);
#else
NewSoftSerial cameraconnection = NewSoftSerial(2, 3);
#endif

Adafruit_VC0706 cam = Adafruit_VC0706(&cameraconnection);

// Using hardware serial on Mega: camera TX conn. to RX1,
// camera RX to TX1, no SoftwareSerial object is required:
//Adafruit_VC0706 cam = Adafruit_VC0706(&Serial1);

void setup() {

  // When using hardware SPI, the SS pin MUST be set to an
  // output (even if not connected or used).  If left as a
  // floating input w/SPI on, this can cause lockuppage.
#if !defined(SOFTWARE_SPI)
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  if(chipSelect != 53) pinMode(53, OUTPUT); // SS on Mega
#else
  if(chipSelect != 10) pinMode(10, OUTPUT); // SS on Uno, etc.
#endif
#endif

  Serial.begin(9600);
  Serial.println("VC0706 Camera snapshot test");
  
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }  
  
  // Try to locate the camera
  if (cam.begin()) {
    Serial.println("Camera Found:");
  } else {
    Serial.println("No camera found?");
    return;
  }
  // Print out the camera version information (optional)
  char *reply = cam.getVersion();
  if (reply == 0) {
    Serial.print("Failed to get version");
  } else {
    Serial.println("-----------------");
    Serial.print(reply);
    Serial.println("-----------------");
  }

  // Set the picture size - you can choose one of 640x480, 320x240 or 160x120 
  // Remember that bigger pictures take longer to transmit!
  
  cam.setImageSize(VC0706_640x480);        // biggest
  //cam.setImageSize(VC0706_320x240);        // medium
  //cam.setImageSize(VC0706_160x120);          // small

  // You can read the size back from the camera (optional, but maybe useful?)
  uint8_t imgsize = cam.getImageSize();
  Serial.print("Image size: ");
  if (imgsize == VC0706_640x480) Serial.println("640x480");
  if (imgsize == VC0706_320x240) Serial.println("320x240");
  if (imgsize == VC0706_160x120) Serial.println("160x120");

  Serial.println("Snap in 3 secs...");
  delay(3000);

  if (! cam.takePicture()) 
    Serial.println("Failed to snap!");
  else 
    Serial.println("Picture taken!");
  
  // Create an image with the name IMAGExx.JPG
  char filename[13];
  strcpy(filename, "IMAGE00.JPG");
  for (int i = 0; i < 100; i++) {
    filename[5] = '0' + i/10;
    filename[6] = '0' + i%10;
    // create if does not exist, do not open existing, write, sync after write
    if (! SD.exists(filename)) {
      break;
    }
  }
  
  // Open the file for writing
  File imgFile = SD.open(filename, FILE_WRITE);

  // Get the size of the image (frame) taken  
  uint16_t jpglen = cam.frameLength();
  Serial.print("Storing ");
  Serial.print(jpglen, DEC);
  Serial.print(" byte image.");

  int32_t time = millis();
  pinMode(8, OUTPUT);
  // Read all the data up to # bytes!
  byte wCount = 0; // For counting # of writes
  while (jpglen > 0) {
    // read 32 bytes at a time;
    uint8_t *buffer;
    uint8_t bytesToRead = min(32, jpglen); // change 32 to 64 for a speedup but may not work with all setups!
    buffer = cam.readPicture(bytesToRead);
    imgFile.write(buffer, bytesToRead);
    if(++wCount >= 64) { // Every 2K, give a little feedback so it doesn't appear locked up
      Serial.print('.');
      wCount = 0;
    }
    //Serial.print("Read ");  Serial.print(bytesToRead, DEC); Serial.println(" bytes");
    jpglen -= bytesToRead;
  }
  imgFile.close();

  time = millis() - time;
  Serial.println("done!");
  Serial.print(time); Serial.println(" ms elapsed");
}

void loop() {
}

 で、これはSDカードに書き込むようになっている。

 私の手持ちの、ArduinoにSDカードをつなぐ手段は、先日から愛用中の「ETHERNET SHIELD 2」に搭載されているSDカードスロットだけだから、とりあえずこれを使う。

 手持ちのSDカードをETHERNET SHIELD 2に挿し、Adafruitのサイトのチュートリアルを参考に回路をブレッドボードに組む。

IMG_3122

 注意する点は2つだ。

  1.  サンプルスケッチをよく読むと、普通のSDカードは10番ピンを使うが、ETHERNET SHIELD 2を使う場合は4番ピンにつながる。なので、サンプルスケッチの中の「#define chipSelect 10」というところを「#define chipSelect 4」に書き換えなければならない。
  2.  メーカーサイトのチュートリアルでは、カメラに添付の10kΩの抵抗をTXの次に直列に二つ入れて、1本目と2本目の間からTXをとり、それをアースしているが、どうもこれだとうまく行かなかった。多分、このチュートリアルは給電が5Vだからだと思う。そこで、アースはそのままに、1本目の手前でTXをとるとうまくいった。
    IMG_3127

 そうやってArduinoをスタートさせると、写真が1枚だけ撮れる。

 下は、そうやって撮った私の顔である。

IMAGE02

 ……むっちゃむさくるしいなあw。

Raspberry Piの入門は

投稿日:

 今はArduinoが面白いのでこればかりいじっているが、ひと段落ついたら世間で人気のRaspberry Piも買ってみようと思っている。

 Raspberry Piは本体だけ買ってもどうにもならないだろうということはだいたい想像がつくので、今日千石電商へ寄った時になにかいいものはないかと店内のポップなど見てみると、「入門用に全部入ってポッキリこのお値段!」というパッケージは、だいたい8千円ぐらいである。

 どうやら、このあたりのものが店頭にあったようだ。


 覚えておきたい。

投稿日:

 Arduinoでいろいろできるようになるには今年の夏ぐらいまでかかるだろうと思っていたが、思いのほか、今日現在でも自分で面白いと思うことができるようになった。

 こうなってみると、夏の休暇には「Raspberry Pi」を買ってみようかという気にもなるではないか。

で、

投稿日:

 まあ、おデコの温度を測ってネットに晒すのはシャレだったが、……。

 脳波は、耳と額の電位差を測って、これをFFTにかければよいのだそうである。

 ……っていうか佐藤よ!何をしようとしている!?お前はどこへ行きたいのだ!!w