說明:
1.
AirView 新增資料存檔功能,紅字為修改部分,可套用未來版本
2.
目前AirView程式雖有記錄time tag,但尚未使用,且林所長只看最高最低點,資料亦已被壓縮,因processing未支援秒以下的小數點,為避免資料存檔的時間混淆,將Arduino端的程式改成1000ms送2筆。
3. 套用時請將原本的 rootDir="D:\\Earthquake Research\\SampledData\\" 改成自己欲存檔的目錄。
3. 套用時請將原本的 rootDir="D:\\Earthquake Research\\SampledData\\" 改成自己欲存檔的目錄。
Processing程式:(新增的修改碼用紅字標示)
// 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程式:
// 測量A0對A1的空氣電壓
// 修改自地震預測研究所所長 林湧森
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;
}
|
沒有留言:
張貼留言