說明

  1. AirView 新增資料存檔功能,紅字為修改部分,可套用未來版本
  2. Processing程式(新增的修改碼用紅字標示)
  3.     套用時請將原本的 rootDir="D:\\Earthquake Research\\SampledData\\" 改成自己欲存檔的目錄

// AirView

// Plot the graph of the air voltage from Arduino

// to predict earthquakes.

// Dyson Lin dysonlin@gmail.com

// 2016-07-30 05:58 UTC+8 V1.0

// 2016-08-10 15:42 UTC+8 V2.1.3 20x data compression. Change background to Black.

// 2016-08-16 21:56 UTC+8 V2.1.9 Plot select range area.

// 2016-08-16 22:17 UTC+8 V2.2.0 Adjust text sizes.

// 2016-08-17 23:43 UTC+8 V2.2.1 Use noLoop() and redraw() to plot graph only after reading new data.

// 2016-08-19 18:40 UTC+8 V2.2.2 10K-Ohom-R Voltage!

// 2016-08-19 19:14 UTC+8 V2.2.3 Water Voltage!

// 2016-08-20 21:04 UTC+8 V2.2.4 220-Ohom-R Voltage!

// 2016-08-24 04:25 UTC+8 V2.2.5 Air Voltage.

// 2016-08-26 17:10 UTC+8 V2.2.6 Fix the minData and maxData bug.

// 2016-08-27 03:53 UTC+8 V2.2.7 Modify plotData(), plotSelectRange().

// 2016-08-29 01:31 UTC+8 V2.2.8 Comment out noLoop() and redraw().

// 2016-08-29 02:23 UTC+8 V2.2.9 Make the window resizable.

// 2016-09-05 22:39 UTC+8 V2.2.9g Save sampled data to file for analysis, modified by ghosty

 

import processing.serial.*;

 

int startTime = 0;

int currentTime = 0;

 

String timeStringStart = null;

String dateStringStart = null;

String timeStringNow = null;

String dateStringNow = null;

 

int graphLeft = 0;

int graphRight = 0;

int graphTop = 0;

int graphBottom = 0;

 

int selectRangeLeft = 0;

int selectRangeRight = 0;

int selectRangeTop = 0;

int selectRangeBottom = 0;

 

int isFirstRead = 1;

 

int maxData = 0;

int minData = 0;

int maxTime = 0;

int minTime = 0;

 

final int compressionRatio = 20;

final int bufferLimit = 2 * compressionRatio; // compression ratio = bufferLimit/2. So bufferLimit must be even.

int [] buffer = new int[bufferLimit];

int [] bufferTime = new int[bufferLimit];

int bufferNumber = 0;

 

int dataLimit = 1000000;

int[] data = new int[dataLimit];

int[] dataTime = new int[dataLimit];

int dataNumber = 0;

 

boolean mouseInZoomArea(int x, int y)

{

  boolean inZoomArea = false;

  int zoomAreaLength = 10;

  int zoomLeft = width - zoomAreaLength;;

  int zoomRight = width;

  int zoomBottom = height;

  int zoomTop = height - zoomAreaLength;

 

  if ((x >= zoomLeft) && (x <= zoomRight) && (y <= zoomBottom) && (y >= zoomTop))

  {

    inZoomArea = true;

  }

 

  return inZoomArea;

}

 

 

//void mouseDragged()

//{

//  if (mouseInZoomArea(mouseX, mouseY))

//  {

//    int newWidth = width + (mouseX - pmouseX);

//    int newHeight = height + (mouseY - pmouseY);

 

//    surface.setSize(newWidth, newHeight);

//  }

//}

 

void setup()

{

  size(1300, 720);

  surface.setResizable(true);

 

  openSerialPort();

  setStartTimeStamp();

}

 

void openSerialPort()

{

  int lf = 10;    // Linefeed in ASCII

  Serial myPort;  // The serial port

 

  // List all the available serial ports

  print("Available serial ports: ");

  printArray(Serial.list());

 

  myPort = new Serial(this, "COM5", 9600);

  myPort.clear(); // Clear buffer

  myPort.bufferUntil(lf); // Trigger serialEvent() only after linefeed is read.

}

 

void setStartTimeStamp()

{

  startTime = millis();

  timeStringStart = nf(hour(), 2) + ":" + nf(minute(), 2) + ":" + nf(second(), 2);

  dateStringStart = year() + "-" + nf(month(), 2) + "-" + nf(day(), 2);

}

 

void setTimeStamp()

{

  currentTime = millis();

  timeStringNow = nf(hour(), 2) + ":" + nf(minute(), 2) + ":" + nf(second(), 2);

  dateStringNow = year() + "-" + nf(month(), 2) + "-" + nf(day(), 2);

}

 

void draw()

{

  //background(204); // gray background

  background(0);  // black background

  stroke(255);

  fill(255);

 

  // Set the location of graph

  graphLeft = 50;

  graphRight = width - 50;

  graphTop = 50;

  graphBottom = height - 100;

  maxTime = graphRight - graphLeft;

 

  background(0);

  setTimeStamp();

  plotSelectRange();

  plotAxes();

  //plotData();

  plotData(graphLeft+3, graphRight, graphBottom-3, graphTop);

}

 

void plotData(int leftBorder, int rightBorder, int bottomBorder, int topBorder) {

  float x1 = 0;

  float y1 = 0;

  float x2 = 0;

  float y2 = 0;

 

  if (dataNumber < 2) {

    return;

  }

 

  stroke(255);

 

  // set first point

  //x1 = graphLeft+3;

  //y1 = map(data[0], minData, maxData, graphBottom-3, graphTop);

  x1 = leftBorder;

  y1 = map(data[0], minData, maxData, bottomBorder, topBorder);

 

  // plot lines

  for (int i=1; i<dataNumber; i++)

  {

    //x2 = map(i, 0, dataNumber-1, graphLeft+3, graphRight); // auto range

    //y2 = map(data[i], minData, maxData, graphBottom-3, graphTop); // auto range

    x2 = map(i, 0, dataNumber-1, leftBorder, rightBorder); // auto range

    y2 = map(data[i], minData, maxData, bottomBorder, topBorder); // auto range

    line(x1, y1, x2, y2);

    x1 = x2;

    y1 = y2;

  }

}

 

void plotSelectRange()

{

  // Set the location of graph

  selectRangeLeft = 100;

  selectRangeRight = width - 100;

  selectRangeBottom = height - 15;

  selectRangeTop = height - 48;

 

  int textSize = 12;

  textSize(textSize);

 

  stroke(0, 128, 0, 128);

  fill(0, 128, 0, 128);

  rect(selectRangeLeft, selectRangeTop, selectRangeRight - selectRangeLeft, selectRangeBottom - selectRangeTop);

 

  stroke(255);

  fill(255);

 

  textAlign(CENTER);

  text(timeStringStart, graphLeft, selectRangeTop + textSize*1);

  text(dateStringStart, graphLeft, selectRangeTop + textSize*2.5);

 

  textAlign(CENTER);

  text(timeStringNow, graphRight, selectRangeTop + textSize*1);

  text(dateStringNow, graphRight, selectRangeTop + textSize*2.5);

 

  plotData(selectRangeLeft, selectRangeRight, selectRangeBottom, selectRangeTop);

}

 

void plotAxes() {

  int textSize = 12;

  float minVoltage = 0;

  float maxVoltage = 0;

 

  textAlign(CENTER);

  textSize = 24;

  textSize(textSize);

  text("Air Voltage", (graphLeft+graphRight)/2, graphTop - textSize);

 

  textSize = 16;

  textSize(textSize);

  text("Time", (graphRight + graphLeft)/2, graphBottom + textSize * 3);

  text("V (mV)", graphLeft, graphTop - textSize);

 

  // plot x-axis

  textSize = 12;

  textSize(textSize);

 

  stroke(0, 128, 0);

  line(graphLeft, graphBottom, graphLeft, graphTop);

  textAlign(RIGHT);

  minVoltage = map(minData, -1023, 1023, -5000, 5000);

  text(round(minVoltage), graphLeft - textSize/2, graphBottom);

 

  maxVoltage = map(maxData, -1023, 1023, -5000, 5000);

  text(round(maxVoltage), graphLeft - textSize/2, graphTop + textSize);

 

  textAlign(CENTER);

  text(timeStringStart, graphLeft, graphBottom + textSize*1.5);

  text(dateStringStart, graphLeft, graphBottom + textSize*2.5);

 

  textAlign(CENTER);

  text(timeStringNow, graphRight, graphBottom + textSize*1.5);

  text(dateStringNow, graphRight, graphBottom + textSize*2.5);

 

  // plot y-axis

  line(graphLeft, graphBottom, graphRight, graphBottom);

  textAlign(CENTER);

 

  textSize = 16;

  textSize(textSize);

  textAlign(CENTER);

  text("Time", (graphRight + graphLeft)/2, graphBottom + textSize * 3);

  text("V (mV)", graphLeft, graphTop - textSize);

}

 

void serialEvent(Serial whichPort) {

  int lf = 10;    // Linefeed in ASCII

  String inString = null;  // Input string from serial port

  int voltage = 0;

 

  inString = whichPort.readStringUntil(lf);

  if (inString == null)

  { 

    return;

  }

 

  inString = trim(inString);

  voltage = int(inString);

  saveData(voltage); //modified by ghosty

 

  if (isFirstRead == 1)

  {

    print("Discard first read: ");

    println(inString);

    isFirstRead = 0;

    return;

  }

 

  buffer[bufferNumber] = voltage;

  bufferTime[bufferNumber] = millis();

 

  if (bufferNumber < bufferLimit-1)

  {

    bufferNumber++;

  } else

  {

    // bufferNumber == bufferLimit-1

    // That means buffer is full

    // Compress data:

    // keep the max and min

    // also keep their order

    int xMax = 0;

    int yMax = 0;

    int xMin = 0;

    int yMin = 0;

    int i = 0;

    String s = null;

 

    yMax = buffer[0];

    xMax = 0;

    yMin = buffer[0];

    xMin = 0;

 

    for (i=1; i<bufferLimit; i++)

    {

      if (buffer[i] > yMax)

      {

        yMax = buffer[i];

        xMax = i;

      }

 

      if (buffer[i] < yMin)

      {

        yMin = buffer[i];

        xMin = i;

      }

    }

 

    bufferNumber = 0;

 

    if (dataNumber == 0)

    {

      maxData = yMax;

      minData = yMin;

    } else {

      if (yMax > maxData)

      {

        maxData = yMax;

      }

 

      if (yMin < minData)

      {

        minData = yMin;

      }

    }

 

    if (xMin < xMax)

    {

      data[dataNumber] = yMin;

      s = "data[" + dataNumber + "] = " + data[dataNumber] + "  Max: " + maxData + "  Min: " + minData;

      println(s);

      dataNumber++;

 

      data[dataNumber] = yMax;

      s = "data[" + dataNumber + "] = " + data[dataNumber] + "  Max: " + maxData + "  Min: " + minData;

      println(s);

      dataNumber++;

    } else

    {

      data[dataNumber] = yMax;

      s = "data[" + dataNumber + "] = " + data[dataNumber] + "  Max: " + maxData + "  Min: " + minData;

      println(s);

      dataNumber++;

 

      data[dataNumber] = yMin;

      s = "data[" + dataNumber + "] = " + data[dataNumber] + "  Max: " + maxData + "  Min: " + minData;

      println(s);

      dataNumber++;

    }

  }

}

 

/*

   modified by ghosty : save data to file

*/

import java.io.*;

String rootDir="D:\\Earthquake Research\\SampledData\\";

void saveData(int voltage)

{

  BufferedWriter output = null;

  try {

    String fileName = rootDir+String.format("air%04d-%02d-%02d.txt", year(), month(), day());

    output = new BufferedWriter(new FileWriter(fileName, true)); //the true will append the new data

    output.write(String.format("%04d-%02d-%02d %02d:%02d:%02d, %d", year(), month(), day(), hour(), minute(), second(), voltage));

    output.newLine();

  }

  catch (IOException e) {

    println("It Broke");

    e.printStackTrace();

  }

  finally {

    if (output != null) {

      try {

        output.close();

      } catch (IOException e) {

        println("Error while closing the writer");

      }

    }

  }

}

 

Arduino程式

// 測量A0A1的空氣電壓

// 修改自地震預測研究所所長 林湧森 2016-07-28 04:29 UTC+8

// 修改者:ghostyguo

// 使用最快取樣速度, 每隔400ms送出最大與最小值

// 2016-08-20 22:30 UTC+8 by

 

int sampleCount;

int maxValue, minValue; //keep extreme value

int whoIsLast = 0; //-1=min, 1=max, 0=undefined;

int sampleCountLimit;

 

void setup()

{

    Serial.begin(9600);

    SetupRunningParameters();

    startNewCycle();

}

 

void SetupRunningParameters()

{

    // find sampleCountLimit in 1000ms

    unsigned long startMicros=micros();

    startNewCycle();

    while (micros()-startMicros<1000000L) {  //原本為400000L, 400ms

        sampling();

    }

    sampleCountLimit = sampleCount;

    // uncomment the following lines to see the sampleCountLimit

    // Serial.print("#");

    // Serial.println(sampleCountLimit);

}

 

void startNewCycle()

{

    maxValue = -10000; //12bit ADC < -1024

    minValue = 10000;  //12bit ADC > 1024

    whoIsLast = 0;

    sampleCount = 0;

}

 

void loop()

{

    sampling();

    if (sampleCount>sampleCountLimit) {

        if (whoIsLast == -1) {

            Serial.println(maxValue);

            Serial.println(minValue);    

        } else if (whoIsLast == 1) {

            Serial.println(minValue);

            Serial.println(maxValue);     

        } else {

            Serial.println("Extreme Value Error");   

        }

        startNewCycle();

    }

}

void sampling()

{

    int sampleValue = analogRead(A1) - analogRead(A0);

    if (minValue > sampleValue) {

        minValue = sampleValue;

        whoIsLast = -1;

    }

    if (maxValue < sampleValue) {

        maxValue = sampleValue;

        whoIsLast = 1;

    }

    ++sampleCount;

}

 

arrow
arrow
    文章標籤
    地震
    全站熱搜

    ghostyguo 發表在 痞客邦 留言(0) 人氣()