2020-10-14 刪除早期版本,以免造成誤解
2018-02-24 <更新>變更參數範圍 訊號偵測CapTime時間內紀錄最大的收訊值預防漏接使用SI4432模組,快速切換頻率並偵測收訊強度,將指定範圍的信號強度顯示於84×48的LCD畫面上,頻率範圍受限於Sl4432模組可用區間為240~930MHz,晝面顯示為點狀模式時晝面更新較快,但不易讀取訊息,條狀模式易讀取但畫面更新較受限,但成本不到台幣500元,就別太計較了。
單一功能鍵 切換頻譜模式及連續訊號偵測模式。
頻譜模式可調整的有頻率範圍,頻率間隔,信號增益,信號強度範圍,頻率尺規位置。
連續訊號偵測模式可調整的有偵測的頻率,信號增益,偵測的時間間隔。
/*
for Arduino IDE 1.0.6 http://yulie-wu.blogspot.tw/2017/04/arduino-240930-mhz-spectrum-analyser.html
2018-02-23 debug and 變更參數範圍 改外接天線,預防漏接 偵測CapTime時間內最大的收訊值
2017-03-11 add frequency pos
2017-03-09 add memory fn & Battery volt & cus
2017-03-04 onCase test OK
2016-12-23 by yulie~
*/
#include <EEPROM.h>
#include <SPI.h>
//#include <SD.h>
//const int chipSelect = 17;
#include "U8glib.h"
int incomingByte = 0; // 用來儲存收進來的 data byte
//U8GLIB_PCD8544 u8g(9, 8, 6, 7, 5); // CLK ,DIN ,CE ,DC ,RST //for test
U8GLIB_PCD8544 u8g(5, 6, 8, 7, 9); // CLK ,DIN ,CE ,DC ,RST //Case OnBoard
#define LINE_MAX 17
uint8_t line_buf[LINE_MAX] = "U8GLIB Console";
uint8_t line_pos = 0;
// setup a text screen to support scrolling
#define ROW_MAX 6
uint8_t screen[ROW_MAX][LINE_MAX];
uint8_t rows, cols;
uint8_t rssi,keepRssi;
unsigned long t,u,v,y,x;
// line height, which matches the selected font (5x7)
#define LINE_PIXEL_HEIGHT 7
#include <RF22.h>
// Singleton instance of the radio
RF22 rf22;
byte Spectrum_gain = 4; // 預設訊號位準
byte Spectrum_base = 6; // 預設雜訊位準
byte sigDet_gain = 4; // 預設訊號位準
byte sigDet_base = 16; // 預設雜訊位準
float sigDet_Frequency = 432.0;
float sigDet_Frequency_1 = 432.0;
byte cus = 4; // 預設畫面尺規位置
byte pos = 40; // 預設 freq target位置
byte j=0;
byte bar=82;//偵測數
byte barW=1;//長條寬度
byte barG=0;//長條圖間隔
byte barT=30;//偵測間隔mS
byte rsi[84];//陣列數量
//int spt[84];//頻譜陣列數
//volatile int encoderPos = 0; // variables changed within interrupts are volatile
String fnStr="spt";
float fScn = 432.0; //Step Frequency /MHz
//float fScn1 = 0;
// float fScn = 0.00f; //Variable to store data read from EEPROM.
//頻譜參數
float fStep=1.0; //Step Frequency /MHz
float fSta=400.0; //Start Frequency /Mhz
float fEnd= fSta + (84 * fStep);
byte fn,oldFn,sl,sl_1,oldsl = 0;
word CapTime = 200 ;
byte runOne = 0;
//boolean SwMu,SwDn,SwUp = 1;
boolean SwFn = 1;// 不知為何無法整批指定
boolean SwMu = 1;// 不知為何無法整批指定
boolean SwSl = 1;
boolean SwDn = 1;
boolean SwUp = 1;
word oscill = 500 ;
byte val,old_val,count;
byte readrssi;
//rssi 18--> -118dB//rssi 230 --> -2dB
void setup(void) {
Serial.begin(115200);
analogReference(INTERNAL);
pinMode(A0,INPUT_PULLUP);//14 A0 Fn
pinMode(A1,INPUT_PULLUP);//15 A1 slect
pinMode(A2,INPUT_PULLUP);//16 A2 up
pinMode(A3,INPUT_PULLUP);//17 A3 down
digitalWrite(9,LOW);
// digitalWrite(14,LOW);
if (!rf22.init())
Serial.println("RF22 init failed");
rf22.setFrequency(432.0); // rf22.setModemConfig(RF22::FSK_PN9_Rb2Fd5);
rf22.setModeRx();
delayMicroseconds(200); // Wait for freq to settle
for(int i = 0 ; i <= bar ; i++ ){
rsi[i]=2;
}
Serial.println("setup ok");
// attachInterrupt(1, irRec, HIGH); // encoder pin on interrupt 0 (pin 2)
// u8g.setRot180(); for test
u8g.firstPage(); do {
u8g.setFont(u8g_font_6x10);
u8g.setPrintPos( 0, 7);
u8g.print("Easy Spectrum ");
u8g.setPrintPos( 0, 17);
u8g.print("240~930 MHz");
u8g.setPrintPos( 0, 25);
u8g.print("ver 2018-02-24");
u8g.setPrintPos( 0, 35);
u8g.print(" WU YUN CHANG");
u8g.setPrintPos( 0, 45);
u8g.print("Battery:");
u8g.print(analogRead(A6) * (1.1 / 1024) * 5.51745);
u8g.print("V"); }
while( u8g.nextPage() );
////取得本地設備電池電壓值
// volt = (analogRead(A0) * (1.1 / 1024) * 5.51745) ; // 220K + 48.7k 分壓 , (220 + 48.7)/48.7=5.51745
delay(5000);
fn = EEPROM.read(0);
// EEPROM.get( eeAddress, fScn );
}
void loop(void) {
// if(digitalRead(A0) == 0 && digitalRead(A0) != SwMu ){ // 按住連續跑
if( digitalRead(A0) != SwMu ){ //按住 連續跑
fn++; if(fn >= 4)fn=0; SwMu != SwMu; //true 或 false(A0)
delay(250);
if( EEPROM.read(0) != fn ){ EEPROM.write(0, fn);} //設定值改變才會執行 write 一次
}
if(millis() - u >= 5000){
u=millis(); }
switch (fn) {
case 0:{SwFnSpectrum(); Spectrum();} break; //頻譜 點
case 1:{SwFnSpectrum(); Spectrum(); } break; //頻譜 線
case 2:{SwFnsigDet(); sigDet(); } break; //顯示脈衝訊號 點
case 3:{SwFnsigDet(); sigDet(); } break; //顯示脈衝訊號 線
case 4:{}
}
}
//================================================================================================================
void Spectrum(){
float f = fSta;
fScn = fSta + ((fEnd-fSta)/2); //for signal Detect
fEnd= fSta + (80 * fStep);
int i=0;
while( f < fEnd + 1){
rf22.setFrequency(f);
delayMicroseconds(1125);//825~1125
// rsi[i]=(rf22.rssiRead()/gain) - base;
// if(rsi[i] <= 1)rsi[i] = 1; //2017-03-06 add
rsi[i]=constrain(((rf22.rssiRead()/Spectrum_gain) - Spectrum_base), 1,40);
// keepRssi=max(keepRssi,rsi[i]);//取得陣列中最大值
f += fStep;
i++;
}
u8g.firstPage();
do {
// u8g.setRot180();
u8g.setFont(u8g_font_6x10);
u8g.setPrintPos( 0, 7);
if(sl==0){u8g.print("Freq adj:");}
if(sl==1){u8g.print("Step adj:");u8g.print(fStep);}
if(sl==2){u8g.print("Gain adj:");u8g.print(Spectrum_gain);}
if(sl==3){u8g.print("Base adj:");u8g.print(Spectrum_base);}
if(sl==4){u8g.print("Cus adj:");u8g.print(cus);}
if(sl==5){
u8g.print("Freq:");
u8g.print(fSta + (pos * fStep),1);
u8g.print("MHz");
for(int j=16;j<40;j+=2)u8g.drawPixel(pos, j ); // Y 軸虛線
}
if(sl != 5){
u8g.setPrintPos( 0, 15);
u8g.print("");
u8g.print(fSta,1);
u8g.print("~");
u8g.print(fEnd,1);
u8g.print("MHz");}
for(int j=0;j<84;j+=20)u8g.drawPixel(j, 18 + cus );
for(int j=0;j<84;j+=10)u8g.drawPixel(j, 19 + cus );
// for(int j=13;j<84;j+=20)u8g.drawPixel(j, 19 + cus );
// u8g.drawFrame(2, 16 , 1, 32);
// u8g.drawPixel(0, 18 );u8g.drawPixel(20, 18 );u8g.drawPixel(40, 18 );u8g.drawPixel(60, 18 );u8g.drawPixel(80, 18 );
// u8g.drawPixel(0, 19 );u8g.drawPixel(20, 19 );u8g.drawPixel(39, 19 );u8g.drawPixel(60, 19 );u8g.drawPixel(80, 19 );
// u8g.drawPixel(10, 19 );u8g.drawPixel(30, 19 );u8g.drawPixel(50, 19 );u8g.drawPixel(70, 19 );
if(fn == 0)for(byte i=0;i <= bar -2; i++)u8g.drawPixel(i, 48 - rsi[i]); //點 時間軸強度(drawPixel 最快)
if(fn == 1)for(byte i=0;i <= bar -2; i++)u8g.drawFrame((barW + barG) * i, 48 - rsi[i], barW, rsi[i]); //線 時間軸強度(drawFrame 快 )
// u8g.drawBox((barW + barG) * i, 48 - rsi[i], barW, rsi[i]); //時間軸強度(drawBox 普)
// u8g.drawLine( i, 48 - rsi[i], i, 48); //時間軸強度(drawLine 慢)
}
while( u8g.nextPage() );
}
//================================================================================================================
void sigDet(){
if(sigDet_Frequency != sigDet_Frequency_1){ //設定值改變才執行一次
sigDet_Frequency_1 = sigDet_Frequency;
rf22.setFrequency(sigDet_Frequency);
}
if(millis() - x >= CapTime){
// Serial.println(millis() - x); //for show real CapTime
x = millis();
//-----------------------------------------------------------------------------------------------------------------
if(CapTime <= 80)rsi[0]=constrain(((rf22.rssiRead()/sigDet_gain) - sigDet_base), 1,40);
if(rsi[0] <= 2)rsi[0] = 2; //2017-03-06 add
for(int i = 0 ; i <= bar ; i++ ){ rsi[ bar - i] = rsi[bar - (i+1)]; }
u8g.firstPage();
do {
// u8g.setRot180();
u8g.setFont(u8g_font_6x10);
u8g.setPrintPos( 0, 7);
if(sl_1==0){ u8g.print("Freq adj:"); }
if(sl_1==1){ u8g.print("Step adj:");u8g.print(fStep); }
if(sl_1==2){ u8g.print("CapT adj:");u8g.print(CapTime); }
if(sl_1==3){ u8g.print("Gain adj:");u8g.print(sigDet_gain); }
if(sl_1==4){ u8g.print("Base adj:");u8g.print(sigDet_base); }
u8g.setPrintPos( 0, 15);
u8g.print(" ");
u8g.print(sigDet_Frequency,1);
u8g.print("MHz");
if(fn == 2)for(byte i=0;i <= bar; i++){u8g.drawPixel(i, 48 - rsi[i]);} //點 時間軸強度
if(fn == 3)for(byte i=0;i <= bar; i++){u8g.drawFrame((barW + barG) * i, 48 - rsi[i], barW, rsi[i]);} //線 時間軸強度
}
while( u8g.nextPage() );
//-----------------------------------------------------------------------------------------------------------------
}
else {
//rsi[0]=constrain(((rf22.rssiRead()/sigDet_gain) - sigDet_base), 1,40);
readrssi=constrain(((rf22.rssiRead()/sigDet_gain) - sigDet_base), 1,40);
rsi[0] = max(rsi[0],readrssi); //預防漏接 偵測CapTime時間內最大的收訊值
//Serial.println(rsi[0]);
}
}
//================================================================================================================
void SwFnSpectrum(){
if( digitalRead(A1) != SwSl ){ //按住 連續跑
sl++;
if(sl >= 6)sl=0;
SwSl != SwSl; //true 或 false
delay(250);
}
switch (sl) {
case 0:{ //adj freq range
if(digitalRead(A3) == 0 && digitalRead(A3) != SwDn ){ // 按住連續跑
fSta -= 10 * fStep; SwDn != SwDn; delay(1); }
if(digitalRead(A2) == 0 && digitalRead(A2) != SwUp ){ // 按住連續跑
fSta += 10 * fStep; SwUp != SwUp; delay(1); }
fSta = constrain(fSta, 240, 930); } break;
case 1:{ //adj freq step
if(digitalRead(A3) == 0 && digitalRead(A3) != SwDn ){ // 按住連續跑
fStep-=0.1; SwDn != SwDn; delay(1);}
if(digitalRead(A2) == 0 && digitalRead(A2) != SwUp ){ // 按住連續跑
fStep+=0.1; SwUp != SwUp; delay(1); }
fStep = constrain(fStep, 0.1, 5.0); } break;
case 2:{//adj GAIN
if(digitalRead(A3) == 0 && digitalRead(A3) != SwDn ){ // 按住連續跑
Spectrum_gain++; SwDn != SwDn; delay(1); }
if(digitalRead(A2) == 0 && digitalRead(A2) != SwUp ){ // 按住連續跑
Spectrum_gain--; SwUp != SwUp; delay(1); }
Spectrum_gain = constrain(Spectrum_gain, 1, 32);} break;
case 3:{//adj base
if(digitalRead(A3) == 0 && digitalRead(A3) != SwDn ){ // 按住連續跑
Spectrum_base++; SwDn != SwDn; delay(80); }
if(digitalRead(A2) == 0 && digitalRead(A2) != SwUp ){ // 按住連續跑
Spectrum_base--; SwUp != SwUp; delay(80); }
Spectrum_base = constrain(Spectrum_base, 1, 64); } break;
case 4:{//adj cus
if(digitalRead(A3) == 0 && digitalRead(A3) != SwDn ){ // 按住連續跑
cus++; SwDn != SwDn; delay(5); }
if(digitalRead(A2) == 0 && digitalRead(A2) != SwUp ){ // 按住連續跑
cus--; SwUp != SwUp; delay(5); }
cus = constrain(cus, 1, 30); } break;
case 5:{//adj pos
if(digitalRead(A3) == 0 && digitalRead(A3) != SwDn ){ // 按住連續跑
pos--; SwDn != SwDn; delay(2); }
if(digitalRead(A2) == 0 && digitalRead(A2) != SwUp ){ // 按住連續跑
pos++; SwUp != SwUp; delay(2); }
pos = constrain(pos, 0, 81); } break;
}
}
//================================================================================================================
void SwFnsigDet(){
if( digitalRead(A1) != SwSl ){ //按住 連續跑
sl_1++;
if(sl_1 >= 5)sl_1=0;
SwSl != SwSl; //true 或 false
delay(250);
}
switch (sl_1) {
case 0:{ //adj freq range
if(digitalRead(A3) == 0 && digitalRead(A3) != SwDn ){ // 按住連續跑
sigDet_Frequency -= fStep; SwDn != SwDn; delay(200); }
if(digitalRead(A2) == 0 && digitalRead(A2) != SwUp ){ // 按住連續跑
sigDet_Frequency += fStep; SwUp != SwUp; delay(200); }
sigDet_Frequency = constrain(sigDet_Frequency, 240, 960); } break;
case 1:{ //adj freq step
if(digitalRead(A3) == 0 && digitalRead(A3) != SwDn ){ // 按住連續跑
fStep-=0.1; SwDn != SwDn; delay(100);}
if(digitalRead(A2) == 0 && digitalRead(A2) != SwUp ){ // 按住連續跑
fStep+=0.1; SwUp != SwUp; delay(100);}
fStep = constrain(fStep, 0.1, 5.0); } break;
case 2:{ //adj cap time
if(digitalRead(A3) == 0 && digitalRead(A3) != SwDn ){ // 按住連續跑
if(CapTime <= 10 && CapTime >= 1 ) CapTime-= 1;
if(CapTime <= 100 && CapTime >= 20 ) CapTime-= 10;
if(CapTime >= 200 ) CapTime-= 100;
SwDn != SwDn; delay(100); }
if(digitalRead(A2) == 0 && digitalRead(A2) != SwUp ){ // 按住連續跑
if(CapTime >= 100 ) CapTime+= 100;
if(CapTime <= 100 && CapTime >= 10 ){CapTime+= 10;}
if(CapTime <= 9 && CapTime >= 1 ) CapTime+= 1;
SwUp != SwUp; delay(100); }
CapTime = constrain(CapTime, 1, 5000); } break;
case 3:{//adj GAIN
if(digitalRead(A3) == 0 && digitalRead(A3) != SwDn ){ // 按住連續跑
sigDet_gain++; SwDn != SwDn; delay(100); }
if(digitalRead(A2) == 0 && digitalRead(A2) != SwUp ){ // 按住連續跑
sigDet_gain--; SwUp != SwUp; delay(100); }
sigDet_gain = constrain(sigDet_gain, 1, 32); } break;
case 4:{//adj base
if(digitalRead(A3) == 0 && digitalRead(A3) != SwDn ){ // 按住連續跑+
sigDet_base++; SwDn != SwDn; delay(80); } // 連續速率
if(digitalRead(A2) == 0 && digitalRead(A2) != SwUp ){ // 按住連續跑-
sigDet_base--; SwUp != SwUp; delay(80); } // 連續速率
sigDet_base = constrain(sigDet_base, 1, 80); } break;
}
}
沒有留言:
張貼留言