An Arduino based sweeper
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

337 lines
6.7 KiB

#include <Wire.h>
#include <SPI.h>
#include <Si570.h>
#include <si5351.h>
#include <LiquidCrystal.h>
#include <Rotary.h>
/*
//Use these 2 lines if you want to use a little OLED display.
#include <ssd1306_tiny.h>
ssd1306_tiny display;
*/
Rotary r = Rotary(3,2); // sets the pins the rotary encoder uses. Must be interrupt pins.
LiquidCrystal lcd(12,11, 7,8,9,10);
long stepInterval = 1000;
uint8_t buttonPressed = 1;
Si5351 si5351;
Si570 *si570=NULL;
#define SI570_I2C_ADDRESS 0x55
char printBuff[20];
#define LOG_AMP A3
//#define WB_POWER_CALIBERATION (-112) //Set your power calibration here
#define WB_POWER_CALIBERATION (-92)
#define BUTTON 4
#define BUTTON2 5 //future use maybe
int dbm_reading = 100;
int mw_reading = 0;
int power_caliberation = WB_POWER_CALIBERATION;
char serial_in[32], c[30], b[30];
unsigned char serial_in_count = 0;
long frequency, fromFrequency=14150000, toFrequency=30000000, stepSize=100000;
#define TUNING A2
int tune, previous = 500;
int count = 0;
int i, pulse;
unsigned long baseTune = 14100000;
boolean sweepBusy = false;
void setup()
{
PCICR |= (1 << PCIE2); //Setup Interrupt Handling
PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
sei();
pinMode(BUTTON,INPUT_PULLUP); //set button input to pullup mode
lcd.begin(16, 2);
printBuff[0] = 0;
printLine1("[RuhNet RF Labs]"); //Startup message
printLine2("Sweeperino v0.03");
delay(2000);
// Start serial and initialize the Si5351
Serial.begin(9600);
analogReference(DEFAULT);
Serial.println("*Sweeperino v0.03\n");
Serial.println("*Testing for Si570\n");
si570 = new Si570(SI570_I2C_ADDRESS, 56320000);
if (si570->status == SI570_ERROR) {
printLine1("Si570 not found. ");
Serial.println("*Si570 Not found\n");
si570 = NULL;
Serial.println("*Si5350 ON");
printLine2("Si5351 Enabled! ");
si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0);
delay(1000);
lcd.clear();
}
else {
Serial.println("*Si570 ON");
printLine2("Si570 ON");
}
setFrequency(14100000); //14.1MHz initial frequency
previous = analogRead(TUNING)/2;
}
/* display routines */
void printLine1(char *c){
if (strcmp(c, printBuff)){
lcd.setCursor(0, 0);
lcd.print(c);
strcpy(printBuff, c);
count++;
}
}
void printLine2(char *c){
lcd.setCursor(0, 1);
lcd.print(c);
}
char *readNumber(char *p, long *number){
*number = 0;
sprintf(c, "#%s", p);
while (*p){
char c = *p;
if ('0' <= c && c <= '9')
*number = (*number * 10) + c - '0';
else
break;
p++;
}
return p;
}
char *skipWhitespace(char *p){
while (*p && (*p == ' ' || *p == ','))
p++;
return p;
}
/* command 'h' */
void sendStatus(){
Serial.write("helo v1\n");
sprintf(c, "from %ld\n", fromFrequency);
Serial.write(c);
sprintf(c, "to %ld\n", toFrequency);
Serial.write(c);
sprintf(c, "step %ld\n", stepSize);
Serial.write(c);
}
void setFrequency(unsigned long f){
if (si570 != NULL)
si570->setFrequency(f);
else
si5351.set_freq((f * 100), SI5351_CLK0);
frequency = f;
}
/* command 'g' to begin sweep
each response begins with an 'r' followed by the frequency and the raw reading from ad8703 via the adc */
void doSweep(){
unsigned long x;
int a;
sweepBusy = 1;
Serial.write("begin\n");
printLine1("Sweeping... ");
for (x = fromFrequency; x < toFrequency; x = x + stepSize){
setFrequency(x);
delay(10);
a = analogRead(LOG_AMP) * 2 + (power_caliberation * 10);
sprintf(c, "r%ld:%d\n", x, a);
Serial.write(c);
}
Serial.write("end\n");
// si5351.set_freq(fromFrequency, 0, SI5351_CLK0);
sweepBusy = 0;
}
/* command 'e' to end sweep */
void endSweep(){
//to be done
}
void readDetector(){
int i = analogRead(3);
sprintf(c, "d%d\n", i);
Serial.write(c);
}
void parseCommand(char *line){
char *p = line;
char command;
while (*p){
p = skipWhitespace(p);
command = *p++;
switch (command){
case 'f' : //from - start frequency
p = readNumber(p, &fromFrequency);
setFrequency(fromFrequency);
break;
case 't':
p = readNumber(p, &toFrequency);
break;
case 's':
p = readNumber(p, &stepSize);
break;
case 'v':
sendStatus();
break;
case 'g':
sendStatus();
doSweep();
break;
case 'r':
readDetector();
break;
case 'o':
case 'w':
case 'n':
break;
case 'i': /* identifies itself */
Serial.write("*iSweeperino 2.0\n");
break;
}
} /* end of the while loop */
}
void acceptCommand(){
int inbyte = 0;
inbyte = Serial.read();
if (inbyte == '\n'){
parseCommand(serial_in);
serial_in_count = 0;
return;
}
if (serial_in_count < sizeof(serial_in)){
serial_in[serial_in_count] = inbyte;
serial_in_count++;
serial_in[serial_in_count] = 0;
}
}
void updateDisplay(){
int j;
sprintf(b, "%9ld", frequency);
sprintf(c, "%.3s.%.3s.%3s ", b, b+3, b+6);
printLine1(c);
//sprintf(c, "%d.%d dBm ", dbm_reading/10, abs(dbm_reading % 10));
sprintf(c, "%d.%d dBm %d.%dmW", dbm_reading/10, abs(dbm_reading % 10), mw_reading/10, abs(mw_reading % 10) );
printLine2(c);
}
void doReading(){
int new_reading = analogRead(LOG_AMP) * 2 + (power_caliberation * 10);
if (abs(new_reading - dbm_reading) > 4){
dbm_reading = new_reading;
mw_reading = pow( 10.0, (dbm_reading) / 10.0);
updateDisplay();
}
}
void doTuning(){
setFrequency(baseTune);
updateDisplay();
/*
count = 0;
if (previous != tune){
setFrequency(baseTune + (10L * (unsigned long)(tune-20)));
updateDisplay();
previous = tune;
}
*/
}
//Main program loop:
void loop(){
if (Serial.available()>0)
acceptCommand();
if (!sweepBusy){
doReading();
doTuning();
}
buttonPressed = digitalRead(BUTTON);
if (buttonPressed) {
lcd.clear();
lcd.setCursor(0,0);
printLine1("Step Size:");
lcd.setCursor(0,1);
lcd.print(stepInterval, DEC);
lcd.print(" Hz");
}
delay(100);
}
//Interrupt processing.
//This is probably kindof messy, but it works...
ISR(PCINT2_vect) {
unsigned char result = r.process();
if (result == DIR_NONE) {
// do nothing
} else if (buttonPressed) {
if (result == DIR_CW) {
if (stepInterval < 1000000) {
stepInterval = stepInterval*10;
} else stepInterval = 1;
} else if (result == DIR_CCW) {
if (stepInterval > 1) {
stepInterval = stepInterval/10;
} else stepInterval = 1000000;
}
}
else if (result == DIR_CW) {
baseTune=baseTune+stepInterval;
}
else if (result == DIR_CCW) {
baseTune=baseTune-stepInterval;
}
}