頻率、速度、加速度

#include <Wire.h> //載入I2C介面函式庫

#include <LiquidCrystal_I2C.h> //載入I2C液晶控制函式庫

LiquidCrystal_I2C lcd(0x27,20,4); // 若LCD 無法啟用,請將0X3F 改為0X27

int a,b,c,d,p,q,r,t_set=3;//宣告變數a b c d 為整數類型 (值域 -32767 ~ 32767)

int a0,b0,c0,i=-1,mode=0,state_1,state_2,state_3;

unsigned long t1,t2,t3;

float x=1,v1,v2,acc,T,frequency;

/////////////////////////////////////////////////////////////////////////////////

void show(int pos){

lcd.clear();

lcd.setCursor(0, 0);

lcd.print("T= ");

lcd.print(T,3);

lcd.print(" sec");

lcd.setCursor(0, 1);

lcd.print("f= ");

lcd.print(frequency,3);

lcd.print(" Hz");

lcd.setCursor(0, 2);

lcd.print("no= ");

lcd.print(i);

lcd.setCursor(0, 3);

lcd.print("measure T & f (");

lcd.print(pos);

lcd.print(")");

}

//////////////////////////////////////////////////////////////////////////////////

void get_frequency(int m){

if(m==1){ //偵測週期頻率 mode1

while(1){

do{a = analogRead(A0); }while( a>= a0);

t1 = micros();

i++;

T = (t1 - t2)/1000000.000000 ;

frequency = 1.000000 /float(T) ;

show(1);

do{ a = analogRead(A0); }while(a<=a0);

do{ a = analogRead(A0); }while(a>=a0);

do{ a = analogRead(A0); }while(a<=a0);

do{ a = analogRead(A0); }while(a>=a0) ;

t2 = micros();

i++;

T = (t2 - t1)/1000000.000000 ;

frequency = 1.000000 /float(T) ;

show(1);

do{ a = analogRead(A0); }while(a<= a0);

do{ a = analogRead(A0); }while(a>= a0);

do{ a = analogRead(A0); }while(a<= a0);

}}else if(m==2){ //偵測週期頻率 mode2

while(1){

do{b = analogRead(A1); }while(b>= b0);

t1 = micros();

i++;

T = (t1 - t2)/1000000.000000 ;

frequency = 1.000000 /float(T) ;

show(2);

do{ b = analogRead(A1); }while(b<=b0);

do{ b = analogRead(A1); }while(b>=b0);

do{ b = analogRead(A1); }while(b<=b0);

do{ b = analogRead(A1); }while(b>=b0) ;

t2 = micros();

i++;

T = (t2 - t1)/1000000.000000 ;

frequency = 1.000000 /float(T) ;

show(2);

do{ b = analogRead(A1); }while(b<= b0);

do{ b = analogRead(A1); }while(b>= b0);

do{ b = analogRead(A1); }while(b<= b0);

}

}else if(m==3){ //偵測週期頻率 mode3

while(1){

do{c = analogRead(A2); }while(c>= c0);

t1 = micros();

i++;

T = (t1 - t2)/1000000.000000 ;

frequency = 1.000000 /float(T) ;

show(3);

do{ c = analogRead(A2); }while(c<=c0);

do{ c = analogRead(A2); }while(c>=c0);

do{ c = analogRead(A2); }while(c<=c0);

do{ c = analogRead(A2); }while(c>=c0) ;

t2 = micros();

i++;

T = (t2 - t1)/1000000.000000 ;

frequency = 1.000000 /float(T) ;

show(3);

do{ c = analogRead(A2); }while(c<= c0);

do{ c = analogRead(A2); }while(c>= c0);

do{ c = analogRead(A2); }while(c<= c0);

}}}

//////////////////////////////////////////////////////////////////////////////////

void get_velocity(int m){

lcd.setCursor(0,2);

lcd.print("no=");

lcd.print(i++);

lcd.setCursor(0,3);

lcd.print("wait for pass...");

if(m==4){ //測量速度 mode4

state_1=0,state_2=0,state_3=0;

while(1){

a = analogRead(A0); //讀取類比腳位A0,可以將0~5V 轉化成 0~1023

b = analogRead(A1); //讀取類比腳位A0,可以將0~5V 轉化成 0~1023

if(a<a0 && state_1==0){

t1 = micros();

state_1=1;

}

if(b<b0 && state_2==0){

t2 = micros();

state_2=1;

}

if(state_1==1 && state_2==1){

long dt = t2-t1;

v1 = 1000000.000/dt;

lcd.clear();

lcd.setCursor(0,0);

lcd.print("Measure V (1 & 2)");

lcd.setCursor(0,1);

lcd.print("v=");

if(v1>0){

lcd.setCursor(3,1);

lcd.print("+");

lcd.print(v1,3);

}else if(v1==0){

lcd.setCursor(3,1);

lcd.print(" ");

lcd.print(v1,3);

}else if(v1<0){

lcd.setCursor(3,1);

lcd.print(v1,3);

}

lcd.print(" cm/s");

break;}}}

if(m==5){ //測量速度 mode5

state_1=0,state_2=0,state_3=0;

while(1){

b = analogRead(A1); //讀取類比腳位A0,可以將0~5V 轉化成 0~1023

c = analogRead(A2); //讀取類比腳位A0,可以將0~5V 轉化成 0~1023

if(b<b0 && state_2==0){

t1 = micros();

state_2=1;

}

if(c<c0 && state_3==0){

t2 = micros();

state_3=1;

}

if(state_2==1 && state_3==1){

long dt = t2-t1;

v1 = 1000000.000/dt;

lcd.clear();

lcd.setCursor(0,0);

lcd.print("Measure V (2 & 3)");

lcd.setCursor(0,1);

lcd.print("v= ");

if(v1>0){

lcd.setCursor(3,1);

lcd.print("+");

lcd.print(v1,3);

}else if(v1==0){

lcd.setCursor(3,1);

lcd.print(" ");

lcd.print(v1,3);

}else if(v1<0){

lcd.setCursor(3,1);

lcd.print(v1,3);

}

lcd.print(" cm/s");

break;}}}

if(m==6){ //測量速度 mode6

state_1=0,state_2=0,state_3=0;

while(1){

a = analogRead(A0); //讀取類比腳位A0,可以將0~5V 轉化成 0~1023

c = analogRead(A2); //讀取類比腳位A0,可以將0~5V 轉化成 0~1023

if(a<a0 && state_1==0){

t1 = micros();

state_1=1;

}

if(c<c0 && state_3==0){

t2 = micros();

state_3=1;

}

if(state_1==1 && state_3==1){

long dt = t2-t1;

v1 = 2000000.000/dt;

lcd.clear();

lcd.setCursor(0,0);

lcd.print("Measure V (1 & 3)");

lcd.setCursor(0,1);

lcd.print("v= ");

if(v1>0){

lcd.setCursor(3,1);

lcd.print("+");

lcd.print(v1,3);

}else if(v1==0){

lcd.setCursor(3,1);

lcd.print(" ");

lcd.print(v1,3);

}else if(v1<0){

lcd.setCursor(3,1);

lcd.print(v1,3);

}

lcd.print(" cm/s");

break;}}}

}

///////////////////////////////////////////////////////////////////////////////////

void calc_accl(){ //計算加速度 mode7

do{

a = analogRead(A0); //讀取類比腳位A0,可以將0~5V 轉化成 0~1023

}while(a>a0);

t1 = micros();

do{

b = analogRead(A1); //讀取類比腳位A0,可以將0~5V 轉化成 0~1023

}while(b>b0);

t2 = micros();

do{

c = analogRead(A2); //讀取類比腳位A0,可以將0~5V 轉化成 0~1023

}while(c>c0);

t3 = micros();

v1 = x*10000.00000/(t2-t1);

v2 = x*10000.00000/(t3-t2);

acc = 2000000.000000*(v2-v1)/(t3-t1);

i++;

lcd.clear();

lcd.setCursor(0,0); //設定LCD游標至第0行,第0列的位置

lcd.print("v1="); //LCD在現在的游標開始顯示 A0= ,每個字元游標會自動前進

lcd.print(v1,3); //LCD在現在的游標顯示變數a的值

lcd.print(" m/s"); //LCD在現在的游標顯示變數a的值

lcd.setCursor(0,1); //設定LCD游標至第0行,第0列的位置

lcd.print("v2="); //LCD在現在的游標開始顯示 A0= ,每個字元游標會自動前進

lcd.print(v2,3); //LCD在現在的游標顯示變數a的值

lcd.print(" m/s"); //LCD在現在的游標顯示變數a的值

lcd.setCursor(0,2); //設定LCD游標至第0行,第0列的位置

lcd.print("a="); //LCD在現在的游標開始顯示 A0= ,每個字元游標會自動前進

lcd.print(acc,5); //LCD在現在的游標顯示變數a的值

lcd.print(" m/s^2"); //LCD在現在的游標顯示變數a的值

lcd.setCursor(0,3); //設定LCD游標至第0行,第0列的位置

lcd.print("no="); //LCD在現在的游標開始顯示 A0= ,每個字元游標會自動前進

lcd.print(i); //LCD在現在的游標顯示變數a的值

delay(1000);

} //計算加速度

/////////////////////////////////////////////////////////////////////////////////////

void setup() {

lcd.init(); //LCD初始化

lcd.backlight(); //LCD 開啟背光

lcd.clear(); // LCD清除畫面

lcd.setCursor(0,0); //設定LCD游標至第0行,第0列的位置

lcd.print("initial..."); //LCD在現在的游標開始顯示 A0= ,每個字元游標會自動前進

a0 = analogRead(A0)/2; //讀取類比腳位A0,可以將0~5V 轉化成 0~1023

b0 = analogRead(A1)/2; //讀取類比腳位A1,可以將0~5V 轉化成 0~1023

c0 = analogRead(A2)/2; //讀取類比腳位A2,可以將0~5V 轉化成 0~1023

///////////////////////////////////////////////////////////////////////////////////////////////

do{ //預備設定模式

lcd.setCursor(0,0);

lcd.print("Choice mode:");

lcd.setCursor(19,3); //設定LCD游標至第0行,第0列的位置

lcd.print(t_set--); //LCD在現在的游標開始顯示 A0= ,每個字元游標會自動前進

delay(1000);

}while(t_set>0); //預備設定模式

////////////////////////////////////////////////////////////////////////////////////////////////

do{ //設定模式

p= analogRead(A0); //讀取類比腳位A0,可以將0~5V 轉化成 0~1023

q= analogRead(A1); //讀取類比腳位A1,可以將0~5V 轉化成 0~1023

r= analogRead(A2); //讀取類比腳位A2,可以將0~5V 轉化成 0~1023

if(p<a0 && q>b0 && r>c0){

mode = 1;

}else if(p>a0 && q<b0 && r>c0){

mode = 2;

}else if(p>a0 && q>b0 && r<c0){

mode = 3;

}else if(p<a0 && q<b0 && r>c0){

mode = 4;

}else if(p>a0 && q<b0 && r<c0){

mode = 5;

}else if(p<a0 && q>b0 && r<c0){

mode = 6;

}else if(p<a0 && q<b0 && r<c0){

mode = 7;

}

}while(mode==0); //設定模式

////////////////////////////////////////////////////////////////////////////////////////////////////

t_set=3;

do{ //顯示設定模式

lcd.setCursor(0,0);

lcd.print("You choose mode: ");

lcd.print(mode);

if(mode==1){

lcd.setCursor(0,1);

lcd.print("Measure Period and");

lcd.setCursor(0,2);

lcd.print("Frequency use hole 1");

}else if(mode==2){

lcd.setCursor(0,1);

lcd.print("Measure Period and");

lcd.setCursor(0,2);

lcd.print("Frequency use hole 2");

}else if(mode==3){

lcd.setCursor(0,1);

lcd.print("Measure Period and");

lcd.setCursor(0,2);

lcd.print("Frequency use hole 3");

}else if(mode==4){

lcd.setCursor(0,1);

lcd.print("Measure Velocity use");

lcd.setCursor(0,2);

lcd.print("hole 1 & 2");

}else if(mode==5){

lcd.setCursor(0,1);

lcd.print("Measure Velocity use");

lcd.setCursor(0,2);

lcd.print("hole 2 & 3");

}else if(mode==6){

lcd.setCursor(0,1);

lcd.print("Measure Velocity use");

lcd.setCursor(0,2);

lcd.print("hole 1 & 3");

}else if(mode==7){

lcd.setCursor(0,1);

lcd.print("Measure Acceleration");

lcd.setCursor(0,2);

lcd.print("use hole 1 & 2 & 3");

}

lcd.setCursor(19,3); //設定LCD游標至第0行,第0列的位置

lcd.print(t_set--); //LCD在現在的游標開始顯示 A0= ,每個字元游標會自動前進

delay(1000);

}while(t_set>0); //顯示設定模式

lcd.clear();

//////////////////////////////////////////////////////////////////////////////////////////////////////////

if(mode==7){

lcd.clear(); // LCD清除畫面

lcd.setCursor(0,3); //設定LCD游標至第0行,第0列的位置

lcd.print("Calibration..."); //LCD在現在的游標開始顯示 A0= ,每個字元游標會自動前進

calc_accl();

x= 9.80665/acc;

}

}

void loop() {

if(mode==1){ get_frequency(mode); }

if(mode==2){ get_frequency(mode); }

if(mode==3){ get_frequency(mode); }

if(mode==4){ get_velocity(mode); }

if(mode==5){ get_velocity(mode); }

if(mode==6){ get_velocity(mode); }

if(mode==7){ calc_accl(); }

}