top of page

2017/2/6

 百葉箱 

百葉箱

 最近は気象観測装置が性能向上して各地にくまなく設置されて天気予報などが正確になされるようになってきました。そのためかはわかりませんが,小中学校に設置されていた百葉箱が軽視されてきています。無くなっている学校もありますし,中身が入っていない学校も多くあります。

 気象現象は私たち人間にとって(生物全体にも)とても大切なものです。インターネットで容易に近隣や全世界の観測結果を知ることができますが,自分で身近な気温や湿度,気圧を測定できると素敵だと思います。

 表示装置 

表示装置

 気圧,温湿度を表示するにはLCDキーパッドシールドを使います配線の必要がなく安定しています。

ブレッドボード

 ブレッドボードで実験 

 Arduinoを手に入れてからセンサーや液晶,RTCなどを購入していろいろな実験をしてなんとか気圧,気温,湿度を測定し時間を計測できるようになりました。ブレッドボードはとても便利に使うことができました。容積が大きくなってしまいますがいろいろと手を加えることができました。

​ センサ

DHT11

MPL115A2

 MPL115A2はI2C接続で使用します。

​ DHT11はOUTからアナログ出力で温度

基板組み立て

 基板組み立て 

 基板に組み立てるとかなり小さく作ることができます。小さくする必要はないのですがそうしてしまいます。各ディバイスにはICソケットを使用しています。

基板設計図

 基板設計図 

 部品面とハンダ面です。データロガシールドを使う場合はDS3231は取り付けません。

ハンダ面

 基板ハンダ面 

 ハンダ面の実物です。手は震えるし,目が悪くなっているしでイモハンダになってしまっています。やり直しもあって見苦しい基板をお見せして済みません。右側のPINヘッダ6本と中央下部のPINヘッダ1本でArduinoと通信します。

 時刻計測 

時刻計測

 時刻計測と気圧・温湿度データを記録するためのSDカードを搭載しているデータロガシールドを使うことにしました。

 データロガーシールドの一部のフリーエリアや,プロトタイプシールドを使って気象観測用の回路をコンパクトに収めることもできますが,ディバイスによる温度上昇などを考えると離れたところに設置できるようにしました。

 スケッチ 

スケッチ

 スケッチはさすがに長くなってしまいました。各部分はセンサやRTC,液晶の組み合わせなので難しいわけではありません。

​ テキストをコピーしてArduinoIDEにペーストしても動きません。インデント用にスペースが入っているので,全てのインデント用スペースを取り除けば,コンパイルできるようです。

A001_LCD_Keypad_SD_RTC_P_T_H_01

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

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

#include <Wire.h>//I2Cを使用
#include <LiquidCrystal.h>//LCDを使用
#include <DS3231.h>//RTCを使用
#include <DHT.h>//DTHを使用

#define MPL115A2 0x60//気圧計のI2Cアドレス
#define num 100//num回の平均をとる
#define DHTPIN A3//入力用のPIN
#define DHTTYPE DHT11//型名

 

LiquidCrystal lcd(8,9,4,5,6,7);//液晶作成

DS3231 RTC;//RTCを作る
DHT dht(DHTPIN, DHTTYPE);//dhtを作成

 

byte year, month, date, DoW, hour, minute, second,prevSecond;
float a0,b1,b2,c12;//気圧の係数のための変数
float Press,Temp;//気圧と気温の変数

void setup() {
  Serial.begin(9600);//serial初期化
  Wire.begin();      //wire初期化
  lcd.begin(16, 2);
  dht.begin();//dhtスタート
  Coefficient();//補正係数取得
  delay(3000);//3秒待ち
}

void loop() {
  float p=0;//pは浮動小数
  int h = dht.readHumidity();
  int t = dht.readTemperature();
  //時刻の取得
    RTC.getTime(year, month, date, DoW, hour, minute, second);
    if (prevSecond != second) {//以前の秒と違ったとき
  //年表示

  lcd.setCursor(0, 0); //年表示

  lcd.print("20");

  lcd.print(year);

  lcd.print("y");

  //日付表示

  if(month<10){lcd.print(" ");}

  lcd.print(month);

  lcd.print("/");

  if(date<10){lcd.print(" ");}

  lcd.print(date);

  //曜日の表示
  lcd.setCursor(0, 1);
  switch (DoW) {
         case 1:lcd.print("Sn");break;
         case 2:lcd.print("Mo");break;
         case 3:lcd.print("Tu");break;
         case 4:lcd.print("We");break;
         case 5:lcd.print("Th");break;
         case 6:lcd.print("Fr");break;
         case 7:lcd.print("St");break;
         default:lcd.print("??");break;
}
  //時刻の表示
      lcd.setCursor(2, 1);
      if(hour<10){lcd.print(" ");}
      lcd.print(hour);lcd.print(":");
      if(minute<10){lcd.print("0");}
      lcd.print(minute);lcd.print(":");
      if(second<10){lcd.print("0");}
  lcd.print(second);
  prevSecond=second;//以前の秒を現在の秒に変更

 

  //気圧の平均取得
    for( int i=0;i<num;i++){
      PressTemp();
      p=p+int (Pressure());}//積算
    if (isnan(h) || isnan(t)) {
      return;  }//h,tが数字でなければERROR帰還
    Press=p/num;//平均
//気圧の表示
    lcd.setCursor(11, 0);//キアツ
    if(Press<1000){lcd.print(" ");}
    lcd.print(int(Press));
    lcd.print("h");//キアツ
//気温表示
  lcd.setCursor(11, 1);//キオン
  if(t<10){lcd.print(" ");}
  lcd.print(t);
  lcd.print("\xdf");//キオン
//湿度表示
  lcd.setCursor(14, 1);//シツド
  if(h<10){lcd.print(" ");}
  lcd.print(h);
  lcd.print("%");//シツド
    }
}

//関数・補助部

int Coefficient(){//係数読み込み
  unsigned int u,l;//ulは2BYTE数
  Wire.beginTransmission(MPL115A2);
  Wire.write(0x04);//04番地から読みます
  if(Wire.endTransmission()!=0)return 5;//0でなければ失敗帰還
    if(Wire.requestFrom(MPL115A2,8)!=8)return 5;//失敗なら帰還 
//係数a0,b1,b2,c12を読み込む 
      //a0の読み込みと計算
      u=Wire.read();l=Wire.read();
      // a0 = (u << 5) + (l >> 3) + (l & 0x07) / 8.0 ;
      a0=((u << 8) + l ) / 8.0 ;
      if( u & 0x80 ) a0 -= 8192.0;
 
      //b1の読み込みと計算
      u=Wire.read();l=Wire.read();
      //b1 = ( ( ( (u & 0x1F) * 0x100 ) + l ) / 8192.0 ) - 3 ;
      b1 = ( ( u <<8) + l ) / 8192.0 ;
      if( u & 0x80 ) b1 -= 8.0;
      
      //b2の読み込みと計算
      u=Wire.read();l=Wire.read();
 //b2 = ( ( ( ( u - 0x80) << 8 ) + l ) / 16384.0 ) - 2 ;
      b2 = ( (u << 8 ) + l ) / 16384.0 ;
      if( u & 0x80 ) b2 -= 4.0;
      
      //c12の読み込みと計算
      u=Wire.read();l=Wire.read();
      //c12 = ( ( ( h * 0x100 ) + l ) / 16777216.0 )  ;
      c12 = ( ( u <<8) + l ) / 32768.0 ;
      if( u & 0x80 ) c12 -= 2.0;
      c12 /= 512.0;
   return 0;
}

int PressTemp(){//気圧と気温を測定
  unsigned int u,l;
 
  Wire.beginTransmission(MPL115A2);
  Wire.write(0x12);//気圧と気温のAD変換開始
  Wire.write(0x01);
  if(Wire.endTransmission()!=0)return 5;//失敗はERROR5
  delay(3);//変換時間待ち

 

  Wire.beginTransmission(MPL115A2);//
  Wire.write(0x00);
  if(Wire.endTransmission()!=0)return 5;//失敗はERROR5帰還
    if(Wire.requestFrom(MPL115A2,4)!=4)return 5;//失敗はERR5帰還
    //気圧
    u=Wire.read();l=Wire.read();
    Press=((u<<8)+l)/64.0;//=(u*256+l)/64.0;
    //気温
    u=Wire.read();l=Wire.read();
    Temp=((u<<8)+l)/64.0;//=(u*256+l)/64.0;
  return 0;
}

float Pressure(){//補正された気圧を求める式
  float d;
 
  d=a0 + (b1 + c12*Temp )*Press + b2*Temp;
  return  d * ( 650.0 / 1023.0 ) + 500.0 ;
}

 

スケッチの説明

 スケッチの説明 

 宣言部では

 1から4行目はインクルードファイルの読み込みです。I2C,液晶,RTC,温湿度計を使用するためです。気圧計はサブルーチンを使っていますのでインクルードファイルは必要としません。

 6から9行目は数や型名を理解しやすい文字に決めています。

 11から13行目はLCD,RTC,温湿度計の実体を作っています。

 15から17行目は変数を宣言してスケッチ全体で使えるようにしています。

 初期設定部では

 シリアル通信,I2C,液晶,温湿度計を初期化して気圧用の係数を求めています。

 繰り返し部では

​ 29行目から31行目までで変数を確保してから気温と湿度を測定しています。

 33行目で年月日時刻を取得して34行目で秒が更新されたか判断しています。更新された場合は36~39行目で年の表示,41~45行目までで日付を表示,47~57行目で曜日を表示,59行目から65行目で時刻を表示しています。66行目で現在時刻の秒を更新します。

 68~89行目では気圧を求めて表示し,気温と湿度を表示します。

 関数・補助部では

 95~127行までで係数を読み込みます。

​ 129~149行は気圧と気温の測定です。

​ 151~156行は測定値から係数と気温を使った気圧の計算を行います。

 牛乳パック百葉箱 

牛乳パック百葉箱

 牛乳パックで百葉箱らしきものを作ってみました。右は液晶表示です。

​ 上はその後作った百葉箱です。

​ 下は現在製作中の百葉箱のスケッチです。時刻合わせとシリアル通信までできています。

​​ 作り方は牛乳パックのタグの百葉箱のページです。

 動作時間 

アンカー 1
PS

 単三乾電池2本で100均のUSB CHARGERで駆動すると3時間2分で電池切れになります。

 表示用LEDを消灯すると6時間1分になります。

 プログラム領域 

 プログラムカラフルクロックのPC制御時刻合わせを導入したところ,

 スケッチに使用できるメモリが少なくなってきました。動作が不安定になる可能性が有ります。

 と表示されました。あまり大きなプログラムはArduinoに適していないようです。朝までできていたデータロギングもできなくなってしまいました。

​ 時計は時計,環境測定は別のCPUを使うべきなのかもしれません。

bottom of page