2016年4月17日 星期日

使用Arduino 製作速度警告器


#Arduino #frequency counter #Speed #33轉 #45轉
Arduino 的便利性使得大家都節省不少時間以及金錢,最近我們老大需要一台可以偵測速度變化的工具,只給我很短的時間,想來想去也只有Arduino 比較適合。
所以利用幾個網上的時間把它完成,因為上班時間實在是很忙沒有時間可以寫程式。
source code如下:


/* FreqMeasure - Example with LCD output
 * http://www.pjrc.com/teensy/td_libs_FreqMeasure.html
 *
 * This example code is in the public domain.
李進衛 修改為我適用的程式程式最原始的出處如上 
Date:2016年3月29日05:40:06
下班時間撰寫的程式

 
 
 */
#include
#include // IIC communication I2C使用的函數
#include // I2C LCD 使用的函數 使用LiquidCrystal目錄之下的LiquidCrystal_I2C.h
//#include "eeprom_anything.h"
#define wait_stable 0
#define set_speed_flag 1 
#define read_speed_frequency 2  

//struct config_type
//{
// float fail_freq = 0.00;
//};

byte mode = 0;
byte sqn = 0;
 float readarray[12];
 float freq33min = 2.14;
 float freq33max = 2.26;
 float freq45min = 2.91;
 float freq45max = 3.09;
double sum=0;
double frequval = 0;
int count=0;
 #define P_buzzer 6
 float frequarray = 0.0;
 boolean f_stable = 0;
 boolean f_3345 = 1;
boolean f_warning = 0; 
//#include
byte ok33counter = 0;
byte ok45counter = 0;
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address

//LiquidCrystal lcd(5, 4, 3, 2, 1, 0);

void setup() {
  Serial.begin(57600);
  pinMode(P_buzzer,OUTPUT); // setting P_buzzer for output
  digitalWrite(P_buzzer,HIGH); // buzzer off
 // lcd.begin(8, 2);
 // lcd.print("Freq:");
   lcd.begin(16,2);         // initialize the lcd for 20 chars 4 lines, turn on backlight
  lcd.backlight(); //點亮背光
  lcd.setCursor(0, 0); //設定游標在第2列第0行
  lcd.print("2016-04-08v02");
  lcd.setCursor(0, 1);
  lcd.print("LeeCW");
delay(1000);
lcd.clear();

  FreqMeasure.begin();
}



//*******************************
//空轉等待轉速穩定等8個信號
//*******************************
//
void speed_stable(void)
{
      lcd.setCursor(0,0);
      lcd.print("Waiting Stable!!");

for (int i = 0; i <8 div="" i="">
{
while(!FreqMeasure.available()); // 等待傳回可以讀計數數值
}


mode = set_speed_flag; // task to go set speed 
sqn = 0; //station = 0 

}




/*
***************************************************************
副程式名稱:speed3345read
傳回值: 沒有
設定值: f_3345 旗標
作用: 33轉,45轉的判斷
先讀進10筆資料--》判斷是33轉或者45轉
***************************************************************
*/

void speed3345read(void)
{
if (f_warning==0)
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("33/45 Decide!!");
}
for ( int ii=0; ii<12 div="" ii="">
{
while(!FreqMeasure.available()); // 等待傳回可以讀計數數值
frequval =  FreqMeasure.read();    // 讀取數值
    frequarray = FreqMeasure.countToFrequency(frequval); //將數值換算成頻率存到矩陣當中
readarray[ii] = frequarray;
Serial.println(readarray[ii]);
}
  for (int i=0;i<12 div="" i="">
  {
    frequarray = readarray[i];
if(frequarray >= freq33min)
{
if (frequarray <=freq33max)
{
ok33counter++;
// Serial.print("ok33counter:");
// Serial.print(i);
// Serial.print("-->");
// Serial.println(ok33counter);
}
}
/*    if ((frequarray>=freq33min)&&((frequarray freq33min))) // 測試陣列中的數量OK的是多少?
{
        ok33counter++;
Serial.print("ok33counter:");
Serial.print(i);
Serial.print("-->");
Serial.println(ok33counter);
} */
    
  }
  for (int i=0;i<12 div="" i="">
  {
    frequarray = readarray[i];
if (frequarray >= freq45min)
{
if (frequarray <= freq45max )
{
ok45counter++;
}
}
/*
    if ((frequarray>=freq45min)&&((frequarray freq45min))) // 測試陣列中的數量OK的是多少?
{
        ok45counter++;
// for debug Serial.print("ok45counter:");
// for debug Serial.print(i);
// for debug Serial.print("-->");
// for debug Serial.println(ok45counter);
} */
    
  }

if (ok33counter >ok45counter)
{
f_3345 = 1;
ok33counter = 0;
ok45counter = 0;
//                Serial.println("Speed is 33!!");
} else{
f_3345 = 0;
ok33counter = 0;
ok45counter = 0;
//                                Serial.println("Speed is 45!!");
}
ok33counter = 0;
ok45counter = 0;
mode = read_speed_frequency;
sqn = 0;
}


void read_freq_000(void)
{
// lcd.clear();
// lcd.setCursor(0,0);
// lcd.print("33/45 Test!!");
for ( int ii=0; ii<12 class="Apple-tab-span" ii="" span="" style="white-space: pre;">
//連續讀12筆資料
{
while(!FreqMeasure.available()); // 等待傳回可以讀計數數值
frequval =  FreqMeasure.read();    // 讀取數值
frequarray = FreqMeasure.countToFrequency(frequval); //將數值換算成頻率存到矩陣當中
readarray[ii] = frequarray;
lcd.setCursor(0, 1);
      lcd.print(frequarray);
      lcd.print("HZ");
 if (f_3345 ==1)
lcd.setCursor(7, 1);
lcd.print("SPEED 33");
}else {
lcd.setCursor(7, 1);
lcd.print("SPEED 45");
}
}
sqn = 1;


}

void read_freq_100(void)
{
                ok33counter = 0;
                ok45counter = 0;
if (f_3345==1) // 33 then 
{
for (int i=0;i<12 div="" i="">
{
frequarray = readarray[i];
// for debug                                                Serial.println(frequarray);

if (frequarray >= freq33min)
{
if (frequarray <= freq33max)
{
ok33counter++;
}
}
/* if ((frequarray >freq33min)&&((frequarray < freq33max)||(frequarray > freq33min))) // 測試陣列中的數量OK的是多少?
{
ok33counter++;
// for debug                                                Serial.print("OK counter is :");
// for debug                                                Serial.println(ok33counter);
} */
    
}  // 讀取陣列中的資料來判斷有超標的資料有幾筆?
if (ok33counter < 8)
{
digitalWrite(P_buzzer,LOW);
ok33counter = 0;
lcd.setCursor(0, 0);
lcd.print("33 Warning !!");
mode = set_speed_flag;
f_warning = 1;
}
ok33counter = 0;
} else 
{
for (int i=0;i<12 div="" i="">
{
frequarray = readarray[i];
if (frequarray >= freq45min)
{
if (frequarray <= freq45max )
{
ok45counter++;
}
}
// if ((frequarray >freq45min)&&((frequarray < freq45max)||(frequarray > freq45min))) // 測試陣列中的數量OK的是多少?
//if ((frequarray >freq33max)||(frequarray < freq33min)) // 測試陣列中的數量OK的是多少?
// {
// ok45counter++;
// }
    
} // 讀取陣列中的資料來判斷有超標的資料有幾筆?
if (ok45counter < 8)
{
digitalWrite(P_buzzer,LOW);
ok45counter = 0;
lcd.setCursor(0, 0);
lcd.print("45 Warning !!");
mode = set_speed_flag;
f_warning = 1;
}
ok45counter = 0;


}
sqn =0;

}
void read_freq(void)
{
// config_type config;
switch(sqn)
{
case 0: read_freq_000(); break;
case 1: read_freq_100(); break;
default : sqn = 0;
}
/*
for ( int ii=0; ii<12 class="Apple-tab-span" ii="" span="" style="white-space: pre;">
//連續讀12筆資料
{
while(!FreqMeasure.available()); // 等待傳回可以讀計數數值
frequval =  FreqMeasure.read();    // 讀取數值
frequarray = FreqMeasure.countToFrequency(frequval); //將數值換算成頻率存到矩陣當中
readarray[ii] = frequarray;
if (f_3345==1) // 33 then 
{
for (int i=0;i<12 div="" i="">
{
frequarray = readarray[i];
if ((frequarray >freq33max)||(frequarray < freq33min)) // 測試陣列中的數量OK的是多少?
{
ok33counter++;
}
    
}  // 讀取陣列中的資料來判斷有超標的資料有幾筆?
if (ok33counter >=3)
{
ok33counter = 0;
lcd.setCursor(0, 0);
lcd.print("33 Warning !!");
}
ok33counter = 0;
} else 
{
for (int i=0;i<12 div="" i="">
{
frequarray = readarray[i];
if ((frequarray >freq33max)||(frequarray < freq33min)) // 測試陣列中的數量OK的是多少?
{
ok45counter++;
}
    
} // 讀取陣列中的資料來判斷有超標的資料有幾筆?
if (ok45counter >=3)
{
ok45counter = 0;
lcd.setCursor(0, 0);
lcd.print("45 Warning !!");
}
ok45counter = 0;


}


  if (FreqMeasure.available()) {
    // average several reading together
    sum = sum + FreqMeasure.read();
    count = count + 1;
    if (count > 2) {
      float frequency = FreqMeasure.countToFrequency(sum / count);
      lcd.setCursor(0, 1);
      lcd.print(frequency);
      lcd.print("HZ");
 //  Serial.println(frequency,DEC);
      sum = 0;
      count = 0;
    }
  } */





}

void loop() {




switch(mode)
{
case wait_stable: speed_stable(); break; //等待轉速穩定
case set_speed_flag : speed3345read(); break; //檢測轉速
case read_speed_frequency: read_freq(); break; //計算頻率
default : mode = 0;
}

/*
這是用來測試矩陣的讀寫判斷是否正常
2016-03-30
李進衛

*/
/*
//******************************************************************************************************
  for (int i=0;i<10 div="" i="">
  {
    frequarray = readarray[i];
    if ((frequarray freq33min)) // 測試陣列中的數量OK的是多少?
    {
            okcounter++;
      }
    
    }
//*******************************************************************************************************    
 */ 
 // speed3345read();
  
}


沒有留言:

如何使用終端機軟體收集來自於Arduino的資料

  將治具使用Micro USB cable 連上電腦 開啟終端機軟體 選擇 Serial🡪按下OK File🡪Log…  設定log file要存放位置,建議檔案名稱直接取名為*.CSV 例如:20231224.csv 按下治具Reset按鍵開始收集資料