LoginSignup
0
0

More than 3 years have passed since last update.

Arduino で気圧をSDカードに保存して、Webからグラフを閲覧する

Posted at

Arduino で気圧をSDカードに保存して、Webからグラフを閲覧します。

まだ書きかけ中ですが。
たぶん、ESP32で書いたほうがいいかもです。

pressureGraph.ino
/*
  Web Server

 A simple web server that shows the value of the analog input pins.
 using an Arduino Wiznet Ethernet shield.

 Circuit:
 * Ethernet shield attached to pins 10, 11, 12, 13
 * Analog inputs attached to pins A0 through A5 (optional)

 created 18 Dec 2009
 by David A. Mellis
 modified 9 Apr 2012
 by Tom Igoe
 modified 02 Sept 2015
 by Arturo Guadalupi

 */
#include <Wire.h>

// setting bmp180 ( pressure sensor )
#include <SFE_BMP180.h>
SFE_BMP180 bmp180; // SDA:A4 SDL:A5

// setting sd
#include <SD.h>
File myFile;

// setting date pin
#define CLK_PIN 8  // CLK:8番ピン
#define DAT_PIN 9  // DAT:9番ピン
#define RST_PIN 10 // RST:10番ピン

// setting date format
struct DateTime{

  boolean CH; //1でClockHalt(停止)だが、0を入れてこの機能使わない前提
  boolean Mode12; //1で12時間表示だが、0を入れて24時間表示で使う前提
  boolean WP; //1でWriteProtectだが0を入れてこの機能使わない前提

  int Date;
  int Month;
  int Week;
  int Year;
  int Seconds;
  int Minutes;
  int Hour;

};

// setting ethernet
#include <SPI.h>
#include <Ethernet.h>
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(192, 168, 0, 177);
EthernetServer server(80);
IPAddress myDns(192, 168, 0, 1);                        

void setup() {

  // setting serial band
  Serial.begin(9600);

  while (!Serial) {
  }
  //Serial.println("Serial init success");

  // setting ethernet
  Ethernet.begin(mac, ip , myDns );
  if (Ethernet.hardwareStatus() == EthernetNoHardware) {
    Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
    while (true) {
      delay(1); // do nothing, no point running without Ethernet hardware
    }
  }
  if (Ethernet.linkStatus() == LinkOFF) {
    //Serial.println("Ethernet cable is not connected.");
  }
  Serial.println("Ethernet init success");

  // start the server
  server.begin();
  //Serial.println(Ethernet.localIP());

  // setting bmp180 ( pressure sensor )
  bool success = bmp180.begin();
  if (success) {
    //Serial.println("BMP180 init success");
  }

  // setting sd card
  if (!SD.begin(4)) {
    while (1);
  }
  //Serial.println("SD init success");

}

void loop() {

  Serial.println("loop init success");

  // web server
  EthernetClient client = server.available();
  if (client) {

    Serial.println("client init success");

    boolean currentLineIsBlank = true;

    while (client.connected()) {
      if (client.available()) {

        char c = client.read();
        Serial.write(c);

        if (c == '\n' && currentLineIsBlank) {

          Serial.println("html init success");

          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");
          client.println("Refresh: 5");
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");

          //
          myFile = SD.open("test.txt");
          if (myFile) {
            while (myFile.available()) {
              client.print(myFile.read());
              client.println("<br/>");
            }
            // ここにグラフを書く
            //client.println("<td><img src=\"https://chart.googleapis.com/chart?chs=100x60&amp;cht=gom&amp;chd=t:"+ String( int(  digitalRead(i) * 100 ) ) +"&amp;chco=FFFFFF,000000\"></td>");
            myFile.close();
          }

          client.println("</html>");
          break;

        }

        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }

      }

    }

    // give the web browser time to receive the data
    delay(1);

    // close the connection:
    client.stop();

  }

  // time  
  byte RTC_clock_image[8];
  DateTime myDateTime;
  read_rtc_byte(RTC_clock_image);
  extract_datetime(RTC_clock_image,myDateTime);
  //yyyy-mm-dd hh:ss:ii week
  /*
  Serial.print(myDateTime.Year);    Serial.print("-");
  Serial.print(myDateTime.Month);   Serial.print("-");
  Serial.print(myDateTime.Date);    Serial.print(" ");
  Serial.print(myDateTime.Hour);    Serial.print(":");
  Serial.print(myDateTime.Minutes); Serial.print(":");
  Serial.print(myDateTime.Seconds); Serial.print("(");
  Serial.print(myDateTime.Week);    Serial.println(")");
  */

  // pressure
  char status;
  double T, P;
  bool success = false;
  status = bmp180.startTemperature();
  //Serial.println("bmp189 init");
  if (status != 0) {

    //Serial.println("bmp189 init success");
    delay(1000);

    status = bmp180.getTemperature(T);

    if (status != 0) {
      status = bmp180.startPressure(3);
      //Serial.println("bmp189 startPressure init");

      if (status != 0) {
        delay(status);
        status = bmp180.getPressure(P, T);

        if (status != 0) {

          //Serial.println("bmp189 startPressure get success");
          /*
          Serial.print("Pressure: ");
          Serial.print(P);
          Serial.println(" hPa");

          Serial.print("Temperature: ");
          Serial.print(T);
          Serial.println(" C");
          */

          // sd card write

          myFile = SD.open("test.txt", FILE_WRITE);
          if (myFile) {

            Serial.println("sd open success");

            myFile.print(myDateTime.Year);    myFile.print("-");
            myFile.print(myDateTime.Month);   myFile.print("-");
            myFile.print(myDateTime.Date);    myFile.print(" ");
            myFile.print(myDateTime.Hour);    myFile.print(":");
            myFile.print(myDateTime.Minutes); myFile.print(":");
            //myFile.print(myDateTime.Seconds); myFile.print("(");
            //myFile.print(myDateTime.Week);    myFile.print(")");

            myFile.print(" ");
            myFile.print(P);
            myFile.print(" ");
            myFile.println(T);

            myFile.close();

          }


        }

      }

    }

  }

}

// ========================================================================
// set read date functions 
// ========================================================================

//RTCからクロックデータをまるごと読みだし、
byte read_rtc_byte(byte image[]){

  pinMode(DAT_PIN, OUTPUT);//DAT_PINのpinmodeをまず送信用で準備
  digitalWrite(RST_PIN, LOW);wait();//最初はRST_PIN下げた状態
  digitalWrite(RST_PIN, HIGH);wait();//開始(RST_PIN 上げ)
  write_1byte(0xbf);//バーストモードのコマンド0xbf送信

  //読み出しに移るのでDAT_PINのピンモード切り替える。CLK_PIN上げのまま
  pinMode(DAT_PIN, INPUT);

  //8byte分続けて読みbyte配列のimageに入れる
  for (int i=0; i<=7; i++){
  read_1byte(image[i]);

  }

  //RST_PIN下げる
  digitalWrite(RST_PIN, LOW); wait(); 

}
void write_1byte(byte data){

  //コマンド等送信 1ビットずつ繰り返し8ビット(1バイト)分送る
  for (int i=0; i <= 7; i++){

    digitalWrite(CLK_PIN, LOW);wait();  //LOW確認
    digitalWrite( DAT_PIN, bitRead(data, i));wait();
    digitalWrite(CLK_PIN, HIGH);wait();  //クロック(LOWからHIGH)で書き込む
    //クロック上げたままで関数を抜ける。

  }  

}
void read_1byte(byte &data){

  //データ受信 1ビットずつ繰り返し8ビット(1バイト)分読みだす
  data = 0;
  for (int i=0; i<=7; i++){ 
    digitalWrite(CLK_PIN, HIGH);wait();//clock上げ。(上げたまま引き継いだ時はそのまま)
    digitalWrite(CLK_PIN, LOW);wait();//clock下げて、
    bitWrite( data,i, digitalRead(DAT_PIN));//読む

    //クロック下げた状態で関数を抜ける
  }  

}
void setImage(byte command, byte image){ //コマンド、書き込みデータ

  pinMode(DAT_PIN, OUTPUT);//DAT_PINのpinmodeを送信用で準備
  digitalWrite(RST_PIN, LOW);wait();//最初はRST_PIN下げた状態
  digitalWrite(RST_PIN, HIGH);wait();//開始(RST_PIN 上げ)
  write_1byte(command);
  write_1byte(image); 
  digitalWrite(CLK_PIN, LOW);wait();//clock下げて、 
  digitalWrite(RST_PIN, LOW);wait();//最後はRST_PIN下げる

}
void getImage(byte command, byte &image){

  pinMode(DAT_PIN, OUTPUT);//DAT_PINのpinmodeを送信用で準備
  digitalWrite(RST_PIN, LOW);wait();//最初はRST_PIN下げた状態
  digitalWrite(RST_PIN, HIGH);wait();//開始(RST_PIN 上げ)
  write_1byte(command);
  pinMode(DAT_PIN, INPUT);//DAT_PINのpinmodeを受信用に切り替え
  read_1byte(image); 
  digitalWrite(RST_PIN, LOW);wait();//最後はRST_PIN下げる  

}
void wait(){

  //Vcc5Vなのでデータシート11ページから待ち時間は1μ秒分とっておけばよい。
  delayMicroseconds(1);

}

//byte配列からの情報抽出
void extract_datetime(byte image[], DateTime &TempDateTime){

  int data10, data1;

  //秒
  data10 = (image[0]>>4)&7; //上位4ビットを0111でマスクする。
  data1 = image[0] & 15; //下位4ビットを1111でマスクする。
  TempDateTime.Seconds =  (data10 * 10) + data1;
  TempDateTime.CH = image[0]>>7;

  //分
  data10 = (image[1]>>4)&7; //上位4ビットを0111でマスクする。
  data1 = image[1] & 15; //下位4ビットを1111でマスクする。
  TempDateTime.Minutes =  (data10 * 10) + data1; 

  //時
  data10 = (image[2]>>4)&3; //上位4ビットを0011でマスクする。
  data1 = image[2] & 15; //下位4ビットを1111でマスクする。
  TempDateTime.Hour =  (data10 * 10) + data1; 
  TempDateTime.Mode12 = image[2]>>7; //12時間表示モード。0にして使わない。

  //日
  data10 = (image[3]>>4)&3; //上位4ビットを0011でマスクする。
  data1 = image[3] & 15; //下位4ビットを1111でマスクする。
  TempDateTime.Date =  (data10 * 10) + data1; 

  //月
  data10 = (image[4]>>4)&1; //上位4ビットを0001でマスクする。
  data1 = image[4] & 15; //下位4ビットを1111でマスクする。
  TempDateTime.Month =  (data10 * 10) + data1; 

  //曜日
  TempDateTime.Week =image[5];

  //年
  data10 = (image[6]>>4) & 15; //上位4ビットを1111でマスクする。
  data1 = image[6] & 15; //下位4ビットを1111でマスクする。
  TempDateTime.Year =  (data10 * 10) + data1 + 2000; 

  //WP
  TempDateTime.WP =image[7]>>7; 

}

// ========================================================================
// set yyyy m d h s i
// ========================================================================

void setYear(int year){ // (ex. 2020
  setImage(0x8C, (((year - 2000)/10)<<4)+(year % 10));
}
void setWeek(byte Week){ // 1:月 2:火 3:水 4:木 5:金 6:土 7:日
  setImage(0x8A, Week);
}
void setMonth(int month){ // 1 - 12
  setImage(0x88,((month/10)<<4)+(month % 10));
}
void setDate(int date){
  setImage(0x86,((date/10)<<4)+(date % 10));
}
void setHour(int hour){ // 0 - 23
  setImage(0x84,((hour/10)<<4)+(hour % 10));
}
void setMinutes(int minutes){
  setImage(0x82,((minutes/10)<<4)+(minutes % 10));  
}
void setSeconds(int seconds){
  setImage(0x80,((seconds/10)<<4)+(seconds % 10));  
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0