頻率、速度、加速度
#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(); }
}