ttoのblog

メモ

ArduinoUNOにeneloopで電源供給

Arduino UNOをスタンドアロンで動かそうと思い、

電源ポートに挿さる乾電池ソケット付きの電源を買おうと思ったのですが、

スタンドアロンで動かすのでUSBポート使わないじゃないか」と思い付き、

手持ちのeneloop stick boosterで

SANYO eneloop USB出力付ハンディ電源(単3形2個セット) KBC-D1BS

SANYO eneloop USB出力付ハンディ電源(単3形2個セット) KBC-D1BS

動くんじゃないの?と繋いでみました。


そしたらちゃんとArduino UNOの電源LEDが点いたので、

今度は「単三Eneloop2本でどのくらい持つのか?」を試したくなりました。


まず、Arduino UNOにSDカードソケット付きEthernet Shieldを挿して、

Arduino イーサネットシールド

Arduino イーサネットシールド

「1秒に1増える変数の値をSDカード上のLOG.txtに書き込む」スケッチを書き込みました。

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

int data = 0;

void setup() {
  //----- Digital Pin -----//
  pinMode(13, OUTPUT);
  
  //----- Serial port -----//
  Serial.begin(9600);
  
  //----- SD card -----//
  Initilize SD card
  Serial.println("Initilizing SD card...");
  if (!SD.begin(4)) {
    Serial.println("Failed!");
    return;
  }
  Serial.println("Suceeded!");
}

void loop() {
  String dataString = "";
  
  dataString += "OK:";
  dataString += String(data);
  
  Serial.println(dataString); //OK:(電源入れてからの秒数)
  
  File dataFile = SD.open("log.txt", FILE_WRITE);
  
  if (dataFile) {
    digitalWrite(13, HIGH);
    dataFile.println(dataString);
    dataFile.close();
    Serial.println("success writing log.txt");
  }
  else {
    Serial.println("error opening log.txt");
  }
  digitalWrite(13, LOW);
  data++;                    // data値は1秒に1増える
  delay(1000);
}

動作確認用にシリアルポートの通信がいくつか書かれていますが、

気にしないでください。


で、一回PCからUSBケーブルを抜き、eneloop stick boosterに繋いで電源ON。

これで電源が落ちた時にLOG.txtを見れば何秒まで動作していたかが分かるという寸法です。

f:id:tto0816:20130224213642j:plain

こんな感じ。(あ、SDカード挿してない…)


電源ON後はほっといて、寝ました。


朝起きてArduino UNOが電池切れで停止していることを確認し、

SDカードを抜いて中のLOG.txtを確認してみました。

すると、

f:id:tto0816:20130224220243j:plain

となっており、約10500秒なので、1時間3600秒だから3時間弱動いていた計算になります。


ここまでやっておいてなんですが、この値はArduinoUNO側の構成によって変わります。


私が考えているのは電源コードレスで、Bluetoothを使ってPCとシリアル通信しようと考えているので、

その場合はBluetoothモジュールの消費電力によって変わるでしょう。


でも、ま、たぶん大きくは変わらないってことで、

電源ONしてすぐに動作停止ってことはないことが分かりました。

センサーで取得した値をリアルタイムでグラフ化したい

随分サボってしまいました。

ちょっとこの遊びにかまける余裕が無かったので。


前回、Ethernetを試すと書いたんですが、

その前にセンサー+Arduinoで取得した値をシリアル経由でPCに送信してPC側でグラフ表示したいです。


調べてみると、やっぱりArduino + Processingかという感じで

Processingを操ってみたいと思います。

という意気込みだけで今回は終わります。

  1. Arduinoで取得したセンサー値をProcessingでPC側に表示してみる
  2. Processingでグラフの表示方法を学ぶ
  3. センサー値をグラフ化してみる

って感じですかね。

いきなりグラフなんて書けないので、

Processingも適当に触りながらユルくやっていきますね…

Arduino Ethernet Shield R3でSDカードにデータを書いてみる(3)

今回こそArduino UNO + Ethernet Shield + SDカード

f:id:tto0816:20130121225627j:plain

でSDカードにデータを書いてみます、と思ったらリファレンススケッチがあるんですね。

#include <SD.h>

// On the Ethernet Shield, CS is pin 4. Note that even if it's not
// used as the CS pin, the hardware CS pin (10 on most Arduino boards,
// 53 on the Mega) must be left as an output or the SD library
// functions will not work.
const int chipSelect = 4;

とあり、SDカードライブラリを使っていきます。

また、Ethernet Shieldでは、ピン4がCS(チップセレクト)で、

もしCSとして使わないとしても

  • ハードウェアCSピン10(Megaではピン53)をOUTPUT設定にする
  • またはSDカードライブラリ関数を使わない

ように注意してねって書いてます。

setup()では

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
  }


  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);
  
  // 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;
  }
  Serial.println("card initialized.");
}

となっており、

  1. シリアル通信の開始
  2. ハードウェアCSピン10を出力設定に
  3. SDカードの初期化

と前の注意に沿いながらセットアップしてます。

実際の処理を行うloop()では、

void loop()
{
  // make a string for assembling the data to log:
  String dataString = "";

  // read three sensors and append to the string:
  for (int analogPin = 0; analogPin < 3; analogPin++) {
    int sensor = analogRead(analogPin);
    dataString += String(sensor);
    if (analogPin < 2) {
      dataString += ","; 
    }
  }

とここまででアナログ0~2ピンのデータを読み、1行の文字列データを作っています。

ここから

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open("datalog.txt", FILE_WRITE);

  // if the file is available, write to it:
  if (dataFile) {
    dataFile.println(dataString);
    dataFile.close();
    // print to the serial port too:
    Serial.println(dataString);
  }  
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.txt");
  } 
}

  1. FileオブジェクトdataFileを生成し、SD.openでdatalog.txtというファイルを参照
  2. SD.openがちゃんと成功し、datalog.txtファイルが開けていることを確認
  3. 開けていれば
    1. 先ほどのアナログピンのデータ(文字列)をファイルに書き込む
    2. ファイルを閉じる
    3. シリアルポートにもデータを書き込む
  4. 開けていなければ、エラーメッセージをシリアルポートに書き込む

という処理をしている模様です。


ソフトウェアの知識が浅いので、

オブジェクトとかクラスとかの解釈で完璧かどうかわからないんですが、

もし記事を読んで下さって間違いに気付いた方がいればコメントして頂けると嬉しいです。



書き込む文字列はアナログピンのデータを読まずに適当な文字列を入れて試してみました。

#include <SD.h>

const int chipSelect = 4;

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
  }
  
  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);
  
  // 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;
  }
  Serial.println("card initialized.");
}

void loop()
{
  String dataString = "Temp";
  
  File dataFile = SD.open("datalog.txt", FILE_WRITE);
  
  if (dataFile) {
    dataFile.println(dataString);
    dataFile.close();
    Serial.println(dataString);
  }  
  else {
    Serial.println("error opening datalog.txt");
  }
  
  delay(1000);
}

結果として、SDカード内のDATALOG.TXT(なぜか大文字になってしまいました)とシリアルモニタに

f:id:tto0816:20130123212814j:plain

というような感じでデータが書けています。ワオ。

これでセンサーで読んだ値をSDカードに書いていくこともできますし、

処理のログを書いていくこともできるようになりました。


次はせっかくなのでEthernetを使用してみたいと思います。

Arduino Ethernet Shield R3でSDカードにデータを書いてみる(2)

前回の続きで、Arduino Ethernet Shield R3に載ってるmicroSDカードスロットを使って

SDカードの利用に挑戦です。


まずはEthernet ShieldをArduino Unoの上にブッ挿して、

f:id:tto0816:20130121225627j:plain

適当なmicroSDカードも挿しておきます。

私は昔のガラケーに使ってた64MBのTranscend製のものを挿しました。


次にIDE側でリファレンスデザインのCardInfoを試して見ることにします。

f:id:tto0816:20130121231338j:plain

からCardInfoを選択してソースコードを表示→書込で

書込が完了したらシリアルモニタでカード情報が確認できます。



実はここでハマりました。

何度やってもSDカードの初期化に失敗してしまうとシリアルモニタに表示されてしまいました。

SDカード自体はPCに挿せば中をエクスプローラで見れますし、テキストファイルも新規に作れます。

なのでググってあーでもないこーでもないとやってみたんですが、

結局、Windowsのディスクの管理でファイルシステムをFAT32でフォーマットしなおしたら、

カード情報の取得に成功しました。

f:id:tto0816:20130121231942j:plain



これで標準のSD.hで問題なくSDカードを操れるはずなので

次回こそはSDカードにデータを書いてみます。

Arduino Ethernet Shield R3でSDカードにデータを書いてみる(1)

Arduino Ethernet Shield R3

載ってるmicroSDカードスロットにカードを挿して、データを書いてみます。

このシールド、現在、amazonでは売り切れており、非常によく似たシールドの

しかないようですが、イーサネットコントローラーはW5100で同じですね。


さてこのシールドをArduino Unoに挿して使用するんですが、

マイクロSDのソケットつきイーサネット・シールドを使用する(14) - フィジカル・コンピューティングを読みながらやってみることにしました。


ただよく分からない(全容が掴めない)ということで、何はともあれリファレンスを参照してみます。

Arduino - Ethernetを見てみると、

http://arduino.cc/en/uploads/Reference/arduino_uno_ethernet_pins.png

Arduino communicates with the shield using the SPI bus. This is on digital pins 11, 12, and 13 on the Uno and pins 50, 51, and 52 on the Mega. On both boards, pin 10 is used as SS. On the Mega, the hardware SS pin, 53, is not used to select the W5100, but it must be kept as an output or the SPI interface won't work.

とあり、標準のEthernetライブラリはデジタルピンD4,10,11,12,13をSPI通信に使うみたいです。

でSPI通信って何ってことで、

Arduino - SPIをざっと読んでみました。


これらから察するに、

標準のEthernetライブラリに沿ってる(はず)のEthernet Shield R3は、

SPIバスをEthernetとSDカードで共用しており、SSピンで使用する方を選択するということですかね?

で他のピンは自由に使っていんですかね?ワオ!


ちょっと情報が多くなったので次回はこれらの情報に沿って実機で試してみます。

読みやすいソースコードを書くために

これを勉強することになりました。

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

同僚と輪講形式の勉強会で勉強します。


今まで可読性については大して気にしてなかったけど、

これからはこうやってブログにもソースを書くし、

何か作ったらgithubにも公開していくつもりなので、

読みやすいソースコードについて学べる良い機会を得ることが出来ました。



自主的に学習する習慣もきっと身につけないといけないんですけど、

やっぱりプライベートは遊んだりしたいですからねえ…

時間を上手く使ってバランス良くしないといけないです。

Arduino+光センサーでLEDを光らせる

3連休が暇でどんどん溶けていく…


Arduino+光センサーでLEDを光らせてみた

あと、光センサーで測定した値をシリアル通信でPC側に送信してみた


まずはソース

void setup() {
  pinMode(13, OUTPUT);
  //Initilize serial
  Serial.begin(9600);
}

void loop() {
  //Read value a sensor value of analogpin A0
  int sensorValue = analogRead(A0);
  
  //Output value to serial
  Serial.println(sensorValue);
  
  //If sensor value > 900, LED lights up.
  if (sensorValue > 900) {
    digitalWrite(13, HIGH);
  } else {
    digitalWrite(13, LOW);
  }
  
  delay(100);
}

なんのこっちゃないソース。

  1. デジタルI/Oの13ピンの出力モード設定
  2. シリアルポートの初期化
  3. アナログI/O A0から読込
  4. シリアルポートへ測定値書込
  5. 測定値が900超えてたら13ピンをHIGH, 超えてなければLOW
  6. 100ms待機

このソースで回路は、

f:id:tto0816:20130113140151j:plain

な感じで。

あ、測定値の閾値900ってのは、先に測定値をシリアルで見て適当に決めた

Arduino IDEにはシリアルモニタ機能もあって

右上のアイコンを押すと

f:id:tto0816:20130113141319j:plain

こんな感じで

シリアルポートからの読込モニタリング、あと書込もできるっぽい。

f:id:tto0816:20130113141327j:plain

明るいとLEDは光らない

f:id:tto0816:20130113132855j:plain

暗くなるとLEDが光る

f:id:tto0816:20130113133041j:plain

できたできた


次はSDカードにデータ書込を試してみたいな