下手の横好きのスクラップブック!!

下手の横好きの、いろいろな記録です。
電子工作・PIC・Arduino・太陽光発電・写真などetc

Arduinoでデータロガーを作る

2011-02-14 | Arduino

Arduinoの統合開発環境である Arduino IDEは相当速いペースでバージョンアップされており、最新のものはArduino-0022になっております。

Arduino-0022をダウンロードして中身をみておりましたら、librariesに「SD」が追加されおり更に「Examples]に「Datalogger」のスケッチがありましたので、早速試してみました。

スケッチ

/*
  SD card datalogger
 
 This example shows how to log data from three analog sensors
 to an SD card using the SD library.
  
 The circuit:
 * analog sensors on analog ins 0, 1, and 2
 * SD card attached to SPI bus as follows:
 ** MOSI - pin 11
 ** MISO - pin 12
 ** CLK - pin 13
 ** CS - pin 10
 
 created  24 Nov 2010
 updated 2 Dec 2010
 by Tom Igoe
 
 This example code is in the public domain.
  
 */

#include

// 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 = 10;

void setup()
{
  Serial.begin(9600);
  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()
{
  // make a string for assembling the data to log:
  String dataString = "";

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

  // 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");
  }
}

 

SDカードのピン番号に関連する部分とデータ入力するピン数を変更しております。


SDカード

動作電圧は 2.7v~3.6v
 Arduinoから3.3vが出力されていますので、vccにはそれをそのまま使います。
 信号ラインも同じ3.3vにしなければなりませんが、今回は簡単な抵抗分圧で接続しました。
 SDカードのピン配列とピン間隔は変則的でカードコネクタを直接ブレッドボードに接続は不能です。
 ブレッドボードへ装着するために、以前に購入してあったサンハヤト社製のメモリーカード変換基板「SDメモリーカード用」を使用しました。
 
 SDカード端子
 9  --
 1  CS
  2  DI
  3  VSS
  4  VDD
  5  SCLK
  6  VSS
  7  DO
  8  --

配線
SDカード部分

センサー部分
データ収集数を4個として、温度および湿度センサーを各2個取り付けました。
状況に応じて入力数は変更可能です。


動作確認
Arduino-0022を起動した後、OPEN→SD→Dataloggerでスケッチが表示できます。
内容を確認し、VerifyでコンパイルさらにUpload toI/O Boardで アップロードします。

SDカードを挿入しリセットをすると記録が始まります。Serial Monitorで内容を確認すると Initializing SD card.....card Initialized と記入され記録が始まります。
SDカードが挿入されていないと、Initializing SD card.....card or not present と表示されます。

SDカードに記録されたデータ

エクセルに外部データとして取り込みグラフ化

 

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

SCP1000 気圧センサーで気圧と温度を測定

2011-02-04 | Arduino

気圧センサーが比較的安く購入できるようになったということを知り、秋葉原に行った時に秋月電子で¥1,800で購入し早速Arduinoで試してみました。

気圧センサーSCP1000の概要

VTIテクノロジー社製の絶対圧気圧センサー
8PINでDIP型になっているのでブレッドボードで接続ができる
電源電圧 2.4~3.3V
インターフェイス SPI(Serial Peripheral Interface)
測定範囲 30Kpa ~ 120kPa(300ヘクトパスカル~1200ヘクトパスカル)

外観

             

接続とスケッチについて、いろいろ情報を入手しましたが、今回はArduinoのホームページから入手した配線図とスケッチを参考にしました。
ライブラリは Arduino のバージョン0018以降にSPIのライブラリがアップされておりますので、それを利用することとしました。


情報入手先URL  http://arduino.cc/en/Tutorial/BarometricPressureSensor

SCP1000は温度と気圧が読み取ることができ、インターフェイスSPIにより情報を取り出します。
温度は16ビットの値を返すようになっており、実際の温度換算は読み取った値を「20」で除算すると℃に表示になります。

2011.2.13追記・修正

データに一部誤りがありましたので修正しました。


気圧は上位3ビット、下位16ビットの2つの部分に分かれており、それを読み込んだ後、上位を16ビットシフトさせ、上位・下位を OR 演算で組み合わせます。
その19ビットの値を読み取ることで気圧の情報が取り出せます。
実際の気圧換算は読み取った値を「4」で除算でパスカル(pa)に換算されます。ヘクトパスカル(hpa)の時はさらに「100」で除算します。

ブレッドボードで配線の状態

SCP1000は3.3Vでの動作になりますので、Arduinoとの電圧レベル変換のため分圧抵抗を挿入しております。
ArduinoからXBeeにより、シリアル無線伝送によりPCに取り込みました。


スケッチ
スケッチは取りあえずArduinoを起動した後 OPEN →SPI→Barometric Pressure Sensorをロードして動作させました。


その結果、温度は正常に計測されましたが、気圧は「2000」前後の値が計測されます。
1気圧 「1013」hpaですのでどう見ても異常な値が出ているようで、このままでは使用できない状況です。
温度は正常に計測されておりますので、各部品と結線は正常と判断しスケッチを調べることにしました。

気圧データの内上位データ読み取り部分
 //Read the pressure data highest 3 bits:
    byte  pressure_data_high = readRegister(0x1F, 1);
    pressure_data_high &= 0b00000111; //you only needs bits 2 to 0

気圧データの内下位データ読み取り部分
 //Read the pressure data lower 16 bits:
    unsigned int pressure_data_low = readRegister(0x20, 2);

16ビットシフト・OR演算・気圧換算
    //combine the two parts into one 19-bit number:
    long pressure = ((pressure_data_high << 16) | pressure_data_low)/4;

以上が気圧データに関する部分ですが見たところ特に異常は無いようにみえます。

そこでArduinoのSerial.print()機能を使い、各変数の値をPCモニターに表示して読み取り結果と演算結果を順次追いかけてみました。

結果の例

 上位データ(pressure_data_high)   101


下位データ(pressure_data_low)   10001010000011 (8835)

OR演算結果(long pressure)/0.25   10001010000011 (8835)

気圧換算結果  2208pa


上記の結果から最終の結果と下位データの結果が全く同じということになりました。
そのことから上位データの16ビットシフトかOR演算がうまく行われていない可能性が出てきました。
いろいろ見ているうちに、上位データと下位データおよび最終結果の変数のデータ型がそれぞれ別のデータ型になっていることに気づき、unsigned longで統一してみたところ正規の値が表示できるようになりました。


変更内容
 // byte  pressure_data_high = readRegister(0x1F, 1);
    unsigned  long  pressure_data_high = readRegister(0x1F, 1);
    pressure_data_high &= 0b00000111; //you only needs bits 2 to 0
 
    //Read the pressure data lower 16 bits:
    unsigned long pressure_data_low = readRegister(0x20, 2);
   
    //combine the two parts into one 19-bit number:
    long pressure = (((pressure_data_high << 16) | pressure_data_low)/4) /100;

そのほかの変更内容

将来Excelにインポートすることを考慮しSerial.print()の部分を変更

No.と各項目の間に「,」を挿入
 // display the temperature & pressure
    n = n + 1;
    Serial.print(n);
    Serial.print(",");
    Serial.print(realTemp);
    Serial.print(",");
    Serial.println( String(pressure));
    delay(1000);

 BIN表示のSerial.print()はカット
 // Serial.print(thisRegister, BIN);
  //Serial.print("\t");

 //Serial.println(thisRegister, BIN);

Tera Termで最終結果をPCに表示

 2011.2.13 追記

マイナス温度の表示修正

温度が氷点下の時正常に表示されないことが判明しましたので、スケッチを一部変更しました。

SCP1000の温度データは符号も含めて14ビットで表現されていますが、温度が氷点下になった時に14ビット目の符号ビットに「1」が入り、表示がマイナスにならなければなりませんが、この符号ビットもそのまま計測データとして計算されておるようです。

そこで温度データを2ビット左にシフトして本来の16ビットとして計算することにしました。

2ビットシフトした分温度換算の時に「 1/4 」に戻しております。

スケッチの変更

 //Read the temperature data
    int tempData = readRegister(0x21, 2);
     
    tempData = tempData << 2 ;
    int realTemp = tempData / 80.0;

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

我が家の太陽光発電  2011年1月の発電量

2011-02-02 | 太陽光発電

 平年の倍近い積雪で太陽電池は雪の中!!

積雪のたびに雪下ろしをしている1階の屋根に設置した太陽電池アレイのみで細々と発電を

続けております。

2月1日に気象庁より発表された「1月の天候」によると、1月は冬型の気圧配置が続き

1986年以来の全国低温となりました。

日照時間は東日本・北日本の太平洋側で多くなり、盛岡でも147.2時間平年比119%です。

しかし、平年の倍近い積雪で太陽電池は雪の下です。盛岡での最深積雪は53cm平年が27cmですのでほヾ倍です。

過去1年間の発電量/消費電力量

1月の発電量/累計発電量

1月の発電量/日射量

1月の最低気温

 

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

VLOOKUP関数の列番号設定の落とし穴

2011-02-01 | エクセルのツボ

VLOOKUP 関数の設定が旨くいかないとの相談を受けました。
VLOOKUP関数は表引きをする時の関数で、VLOOKUP(検索値,範囲,列番号,検索型)

 と引数が4個必要です。検索値を範囲で指定した表の左側の列で上から検索し、

見つかった行の左側から列番号目の列のデータを返します。

相談を受けた内容を下の表で再現すると、D6のセルに所属NO.の番号を入力するとE6の

セルに該当する所属名が表示されるという内容です。

 

E6のセルには次のように計算式が入力されており特に問題が無いようにも見えます。
=IF(D6="","",VLOOKUP(D6,$H$6:$M$11,2,FALSE))

しかし、結果は所属名のセルに「0」が表示されるだけで希望するデータが表示できない状況です。

いろいろ調べていくうちに、シート内の別の表のレイアウトの関係で、検索する範囲の

別表の列が結合されていることが解りました。

通常は別表の表の列数「2」を指定すればOKなのですが、この場合列が結合されている

関係で列を指定する列番号の数値が変わることになります。

別表の列数を最初からカウントしていくと、所属名が入力されている最初のセルは左から

4番目になります。

従って列番号の列数の指定を「2」から「4」に変更すると正常に検索値が表示されるように

なりました。
=IF(D6="","",VLOOKUP(D6,$H$6:$M$11,4,FALSE))

なお、検索範囲の指定は「$H$6:$M$11」、「$H$6:$K$11」どちらでもOKのようです。

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする