Uppdateringar

Uppdateringar
Här finns programuppdateringar, programexempel och även ombyggnadsalternativ.
Programkoderna kopieras och klistras in i Arduino editorn för uppdatering av programmet.
Sidan kommer att uppdateras när nya varianter dyker upp.


MJUKVARA

HAMkit ver. 1.1
- Ljudavbrott var 5 sek. vid minnesscanning åtgärdat.
- CTCSS frekvensvisning borttagen p.g.a. minnesbrist efter programändring.
- Buggfix vid läsning från EEPROM.
(Vid inläsning av ny RX & TX frekvens från EEPROM ändrades tidigare bara visningen i displayen
men inte den valda frekvensen)

VHF variant 134-174 MHz ver.1.1

//HAM kit v.1.1 VHF 210118

/* Arduino NANO

Sketch uses 30656 bytes (99%) of program storage space. Maximum is 30720 bytes.

Global variables use 1046 bytes (51%) of dynamic memory, leaving 1002 bytes for local variables. Maximum is 2048 bytes.

V.1.1: Scanner ändrad. CTCSS frekvensvisning borttagen. Buggfix EEPROM.

*/

//RADIO

#include <stdio.h>

#include <SoftwareSerial.h>

#include "DRA818.h"

#include <EEPROM.h>

#define RX 3 // arduino serial RX pin to the DRA818 TX pin

#define TX 4 // arduino serial TX pin to the DRA818 RX pin

int BUTTON = 2;

float TIMEBUTTON;//Tid för långtryck på BUTTON

int count;

float stime;

float xx;

float RXFREQ = 145.7500;//RX Startfrekvens (MHz)(Om EEPROM är tomt)

float TXFREQ = 145.1500;//TX Startfrekvens (MHz)

int SCAN;

float freq = RXFREQ;//Scannerfrekvens

uint8_t SQ = 1; //Squelch vid start (0-8)

uint8_t VOL = 4; //Ljudvolym vid start (1-8)

uint8_t CTCSS = 16; //CTCSS kanal vid start (0-38)

uint8_t CTCSSRX;

int MEM; //Menu memory

float timerR;

float timerT;

float TIMEOUT;

String active;

String CTEXT;//Text för CTCSS

int MHZ;

int SAVE;

int eeAddress;

int POWER = 1;

int TONE;

int RXTX;


struct MyObject { //Data som Sparas/Läses från EEPROM

float fieldRX;//RXFREQ

float fieldTX;//TXFREQ

int fieldSQ;

int fieldVOL;

uint8_t fieldCTCSS;

double fieldF0;//RX Minne 0-5...

double fieldF1;

double fieldF2;

double fieldF3;

double fieldF4;

double fieldF5;

double fieldT0;//TX Minne 0-5...

double fieldT1;

double fieldT2;

double fieldT3;

double fieldT4;

double fieldT5;

uint8_t fieldCTCSS0;//CTCSS Minne 0-5...

uint8_t fieldCTCSS1;

uint8_t fieldCTCSS2;

uint8_t fieldCTCSS3;

uint8_t fieldCTCSS4;

uint8_t fieldCTCSS5;

};

SoftwareSerial *dra_serial; // Serial connection to DRA818

DRA818 *dra; // the DRA object once instanciated


double myRX[] = {1456500, 1456000, 1457000, 1568000, 1566500, 1567000}; //RX lista (MHZ*10000)

double myTX[] = {1450500, 1450000, 1451000, 1568000, 1566500, 1567000}; //TX lista

uint8_t myCTCSS[] = {16, 16, 16, 0, 0, 0}; //CTCSS kanallista

int countfreq;//Scanminne

int countmem;//Kanalminne

int pausescan;//Detekterad kanal


//DISPLAY

#include <SPI.h>

#include <Wire.h>

#include <Adafruit_GFX.h>

#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels

#define SCREEN_HEIGHT 32 // OLED display height, in pixels

#define OLED_RESET -1 // Reset pin #

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);



void configure() //Starta upp radio med inställningar

{

dra = new DRA818(dra_serial, DRA818_VHF);

dra->handshake();

dra->group(DRA818_12K5, RXFREQ, TXFREQ, CTCSS, SQ, CTCSSRX);

dra->volume(VOL);

dra->filters(true, true, true);

}


void NEXT() //Nästa menyval

{

TIMEOUT = millis();

timerR = millis();

count++;

MEM = 0;

MHZ = 0;

TIMEBUTTON = millis();

SCAN = 0;

xx = millis();

}


void saving() //Spara inställningar

{

display.clearDisplay();

display.setTextSize(1); // Normal 1:1 pixel scale

display.setTextColor(SSD1306_WHITE); // Draw white text

display.setCursor(35, 12);

if (SCAN > 3)display.print(F("Saved"));

if (SAVE == 1)display.print(F("EEPROM"));

display.display();

delay(500);

}


void setup() {


Serial.begin(9600);

dra_serial = new SoftwareSerial(RX, TX); // Instantiate the Software Serial Object.


//DISP:


if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32

// Serial.println(F("SSD1306 allocation failed"));

for (;;); // Don't proceed, loop forever

}


display.clearDisplay();

display.setTextSize(1); // Normal 1:1 pixel scale

display.setTextColor(SSD1306_WHITE); // Draw white text

display.setCursor(35, 12); // Startuptext position

display.print(F("HAM kit v.1.1")); //Startuptext

display.display();

delay(500); //Tid som startuptext visas (ms)

//configure();


display.clearDisplay();// Clear the buffer


timerR = millis();

timerT = millis();

pinMode(13, OUTPUT); //Styrning uteffekt H/L

pinMode(BUTTON, INPUT_PULLUP); //Tryckknapp

pinMode(5, INPUT_PULLUP); //VredNER,10-11

pinMode(6, INPUT_PULLUP); //VredUPP, 11-10

digitalWrite(13, POWER); //Sätt utefekt

pinMode(8, OUTPUT); //Ljudförstärkarutgång

pinMode(7, INPUT); //Vid radiosignal, aktivera ljudförstärkarutgång

// pinMode(12, OUTPUT); //Aktivera sändning

//digitalWrite(12, 0); //Sätt utefekt

MyObject customVar; //Variable to store custom object read from EEPROM.

EEPROM.get( eeAddress, customVar );//Läs från EEPROM:

if(customVar.fieldRX>100)//Kontrollera att EEPROM inte är tomt innan inläsning

{

RXFREQ = customVar.fieldRX; //RX Startfrekvens

TXFREQ = customVar.fieldTX; //TX Startfrekvens

SQ = customVar.fieldSQ; //Squelch start

VOL = customVar.fieldVOL; //Ljudvolym start

CTCSS = customVar.fieldCTCSS; //CTCSS start

myRX[0] = customVar.fieldF0; //RX frekvens lista 0-5...

myRX[1] = customVar.fieldF1;

myRX[2] = customVar.fieldF2;

myRX[3] = customVar.fieldF3;

myRX[4] = customVar.fieldF4;

myRX[5] = customVar.fieldF5;

myTX[0] = customVar.fieldT0; //TX frekvens lista 0-5...

myTX[1] = customVar.fieldT1;

myTX[2] = customVar.fieldT2;

myTX[3] = customVar.fieldT3;

myTX[4] = customVar.fieldT4;

myTX[5] = customVar.fieldT5;

myCTCSS[0] = customVar.fieldCTCSS0;//CTCSS lista 0-5...

myCTCSS[1] = customVar.fieldCTCSS1;

myCTCSS[2] = customVar.fieldCTCSS2;

myCTCSS[3] = customVar.fieldCTCSS3;

myCTCSS[4] = customVar.fieldCTCSS4;

myCTCSS[5] = customVar.fieldCTCSS5;

}

configure();

}



void loop() {


if (digitalRead(7) == 0 && VOL != 0) //Vid radiosignal, aktivera ljud

{

digitalWrite(8, HIGH);

}

else digitalWrite(8, LOW);


if (!dra) return; // do nothing if DRA configuration failed


if (digitalRead(BUTTON) != 0)

{

TIMEBUTTON = millis();

}


if (count == 0)active = "VOL"; //VOLMENU

if (count == 1)active = "RX"; //RXMENU

if (count == 2)active = "TX"; //TXMENU

if (count == 3)active = "SCAN"; //SCANMENU

if (count == 4)active = "SQ"; //SQMENU

if (count == 5)active = "CTCSS"; //CTCSSMENU

if (count == 6)active = "EEPROM"; //EEPROMMENU


if (MEM == 0)

{

disp();

MEM = 1;

}


if (digitalRead(5) == 0 && digitalRead(6) == 1 && ((millis() - timerR) > 20)) //Vid vridning moturs (50 ms)

{

TIMEOUT = millis();


if (count == 0) //VOLMENU

{

if (SCAN != 3)

{

VOL -= 1;

if ((VOL < 0) || (VOL > 8))VOL = 0;

if (VOL > 0)dra->volume(VOL);

}

if (SCAN == 3)

{

countmem--;

if (countmem < 0)countmem = 5;

RXFREQ = (float)myRX[countmem] / 10000; //Läs i listan

TXFREQ = (float)myTX[countmem] / 10000;

CTCSS = myCTCSS[countmem];

dra->group(DRA818_12K5, RXFREQ, TXFREQ, CTCSS, SQ, CTCSSRX);

}

MEM = 0;

}


if (count == 1) //RXMENU

{

double FR = (RXFREQ * 10000);

if (MHZ == 0)FR -= 125; //12.5kHz step

if (MHZ == 1)FR -= 1000;

if (MHZ == 2)FR -= 10000;

if (MHZ == 3)FR -= 100000;

RXFREQ = (float)(FR / 10000), 4;

if (MHZ == 4)TONE = 0;

if (TONE == 0)CTCSSRX = 0;

if (RXTX == 1)TXFREQ = RXFREQ;

MEM = 0;

dra->group(DRA818_12K5, RXFREQ, TXFREQ, CTCSS, SQ, CTCSSRX);

}


if (count == 2) //TXMENU

{

double FT = (TXFREQ * 10000);

if (MHZ == 0)FT -= 125; //12.5kHz step

if (MHZ == 1)FT -= 1000;

if (MHZ == 2)FT -= 10000;

if (MHZ == 3)FT -= 100000;

TXFREQ = (float)(FT / 10000), 4;

if (MHZ == 4)POWER = 1;

if (MHZ == 5)RXTX = 0;

MEM = 0;

dra->group(DRA818_12K5, RXFREQ, TXFREQ, CTCSS, SQ, CTCSSRX);

}

if (count == 3) //SCANMENU

{

SCAN -= 1;

if (SCAN < 0)SCAN = 0;

MEM = 0;

}


if (count == 4)//SQMENU

{

SQ -= 1;

if ((SQ < 0) || (SQ > 8))SQ = 0;

MEM = 0;

dra->group(DRA818_12K5, RXFREQ, TXFREQ, CTCSS, SQ, CTCSSRX);

}


if (count == 5)//CTCSSMENU

{

CTCSS -= 1;

if (CTCSS < 0 || CTCSS == 255)CTCSS = 38; //38

if (TONE == 1)CTCSSRX = CTCSS;

MEM = 0;

dra->group(DRA818_12K5, RXFREQ, TXFREQ, CTCSS, SQ, CTCSSRX);

}

if (count == 6)//EEPROMMENU

{

SAVE -= 1;

if (SAVE < 0)SAVE = 1;

MEM = 0;

}

timerR = millis();

}


if (digitalRead(5) == 0 && digitalRead(6) == 0 && ((millis() - timerR) > 20)) //Vid vridning medurs (50 ms)

{

TIMEOUT = millis();

if (count == 0) //VOLMENU

{

if (SCAN != 3)

{

VOL += 1;

if (VOL > 8)VOL = 8;

dra->volume(VOL);

}

if (SCAN == 3)

{

countmem++;

if (countmem > 5)countmem = 0;

RXFREQ = (float)myRX[countmem] / 10000; //Läs i listan

TXFREQ = (float)myTX[countmem] / 10000;

CTCSS = myCTCSS[countmem];

dra->group(DRA818_12K5, RXFREQ, TXFREQ, CTCSS, SQ, CTCSSRX);

}

MEM = 0;

}


if (count == 1) //RXMENU

{

double FR = (RXFREQ * 10000);

if (MHZ == 0)FR += 125; //12.5kHz step

if (MHZ == 1)FR += 1000;

if (MHZ == 2)FR += 10000;

if (MHZ == 3)FR += 100000;

RXFREQ = (float)(FR / 10000), 4;

if (MHZ == 4)TONE = 1;

if (TONE == 1)CTCSSRX = CTCSS;

if (RXTX == 1)TXFREQ = RXFREQ;

MEM = 0;

dra->group(DRA818_12K5, RXFREQ, TXFREQ, CTCSS, SQ, CTCSSRX);

}


if (count == 2)//TXMENU

{

double FT = (TXFREQ * 10000);

if (MHZ == 0)FT += 125; //12.5kHz step

if (MHZ == 1)FT += 1000;

if (MHZ == 2)FT += 10000;

if (MHZ == 3)FT += 100000;

TXFREQ = (float)(FT / 10000), 4;

if (MHZ == 4)POWER = 0;

if (MHZ == 5)RXTX = 1;

MEM = 0;

dra->group(DRA818_12K5, RXFREQ, TXFREQ, CTCSS, SQ, CTCSSRX);

}

if (count == 3) //SCANMENU

{

SCAN += 1;

if (SCAN > 9)SCAN = 0;

MEM = 0;

}

if (count == 4)//SQMENU

{

SQ += 1;

if (SQ > 8)SQ = 0;

MEM = 0;

dra->group(DRA818_12K5, RXFREQ, TXFREQ, CTCSS, SQ, CTCSSRX);

}


if (count == 5)//CTCSSMENU

{

CTCSS += 1;

if (CTCSS > 38)CTCSS = 0; //38 max

if (TONE == 1)CTCSSRX = CTCSS;

MEM = 0;

dra->group(DRA818_12K5, RXFREQ, TXFREQ, CTCSS, SQ, CTCSSRX);

}


if (count == 6)//EEPROMMENU

{

SAVE += 1;

if (SAVE > 1)SAVE = 0;

MEM = 0;

}

timerR = millis();

}


if (count == 1 || count == 2) //RX eller TX

{

if ((digitalRead(BUTTON) == 0) && (millis() - timerT > 500)) //Stega MHz...

{

timerT = millis();

TIMEOUT = millis();

}

if ((millis() - timerT < 399) && ((millis() - xx) > 1200))

{

MHZ++;

if (count == 1 && MHZ > 4)MHZ = 0; //RX

if (MHZ > 5)MHZ = 0;

MEM = 0;

delay(500);

}


}


if ((digitalRead(BUTTON) == 0) && (millis() - TIMEBUTTON) > 1000)

{

NEXT();

digitalWrite(13, POWER); //Sätt uteffekt

if (RXTX == 1)TXFREQ = RXFREQ;

MHZ = 0;

if (SAVE == 1) //Spara i EEPROM?

{

MyObject customVar = {

RXFREQ,

TXFREQ,

SQ,

VOL,

CTCSS,

myRX[0], myRX[1], myRX[2], myRX[3], myRX[4], myRX[5],

myTX[0], myTX[1], myTX[2], myTX[3], myTX[4], myTX[5],

myCTCSS[0], myCTCSS[1], myCTCSS[2], myCTCSS[3], myCTCSS[4], myCTCSS[5]

};

eeAddress = 0;

EEPROM.put(eeAddress, customVar);

saving();

SAVE = 0;

}

}


if (((millis() - TIMEOUT) > 3000) && count != 0)//Vid 3s inaktivitet.

{

count = 0;

MEM = 0;

SAVE = 0;

if (RXTX == 1)TXFREQ = RXFREQ;

digitalWrite(13, POWER); //Sätt utefekt


if (SCAN > 3)

{

myRX[SCAN - 4] = (double)RXFREQ * 10000; //Lagra i listan

myTX[SCAN - 4] = (double)TXFREQ * 10000;

myCTCSS[SCAN - 4] = CTCSS;

saving();

SCAN = 0;

}

dra->group(DRA818_12K5, RXFREQ, TXFREQ, CTCSS, SQ, CTCSSRX);

}//


if (count > 6)count = 0; //Efter sista menyn, gå till meny 0.

if (TXFREQ > DRA818_VHF_MAX) TXFREQ = DRA818_VHF_MIN; // when DRA818_VHF_MAX (174.0) is reached, start over at DRA818_VHF_MIN (134.0)

if (TXFREQ < DRA818_VHF_MIN) TXFREQ = DRA818_VHF_MAX;

if (RXFREQ > DRA818_VHF_MAX) RXFREQ = DRA818_VHF_MIN; // when DRA818_VHF_MAX (174.0) is reached, start over at DRA818_VHF_MIN (134.0)

if (RXFREQ < DRA818_VHF_MIN) RXFREQ = DRA818_VHF_MAX;


if (SCAN > 0 && SCAN < 3 && count == 0)SCANNER();


}//Loop



void SCANNER()

{

int nostore = 0;


if (digitalRead(BUTTON) == 0)goto quit;//Gå till nästa kanal vid tryck

if (pausescan == 0 )//&& digitalRead(7) == 1)

{

if (dra->scan(freq))

{

pausescan = 1;

dra->group(DRA818_12K5, freq, TXFREQ, CTCSS, SQ, CTCSSRX);

stime = millis();


if (SCAN == 1)

{

for (int i = 0; i < 5; i++)

{

if ((float)(myRX[i] / 10000) == freq)nostore = 1;

}

if (nostore != 1)

{

myRX[countfreq] = myTX[countfreq] = (double)freq * 10000; //Lagra i listan

countfreq++;

if (countfreq > 5)countfreq = 0;

}

}


}


}//End pausescan


if ((millis() - stime) > 5000)//Om 5 sek har gått, sök vidare

{

quit:

if (SCAN == 1)

{

double FRE = (freq * 10000); //Gör om till double för bättre precision

if (TXFREQ > RXFREQ)

{

FRE += 125; //12.5kHz step

freq = (float)(FRE / 10000), 4;

if (freq > TXFREQ) freq = RXFREQ;

// if (freq < RXFREQ) freq = TXFREQ;

}

if (TXFREQ < RXFREQ)

{

FRE -= 125; //12.5kHz step

freq = (float)(FRE / 10000), 4;

if (freq < TXFREQ) freq = RXFREQ;

// if (freq > RXFREQ) freq = TXFREQ;

}

pausescan=0;

}


if (SCAN == 2 && pausescan == 0 && digitalRead(7) == 1)//Om signal ej är kvar, sök vidare, annars vänta

{

countfreq++;

if (countfreq > 5)countfreq = 0;

if (myRX[countfreq] >= DRA818_VHF_MIN)freq = (myRX[countfreq] / 10000);

}

if(digitalRead(7) == 1)pausescan = 0;

disp();

}


}//End scanner


void disp() //Visa i display

{

display.clearDisplay();

display.setTextSize(1); // Normal 1:1 pixel scale

display.setTextColor(SSD1306_WHITE); // Draw white text

display.setCursor(0, 0); // Start at top-left corner

String POWERTXT;

String TONETEXT;

if (POWER == 0)POWERTXT = " MHz H";

if (POWER == 1)POWERTXT = " MHz L";

if (TONE == 0)TONETEXT = " MHz ";

if (TONE == 1)TONETEXT = " MHz T";


if (SCAN != 1)display.print(F("RX: "));

if (SCAN == 1)display.print(F("RX1: "));

if (SCAN != 2)display.println(String(RXFREQ, 4) + TONETEXT);

if (SCAN == 2)display.println(String("MEM ") + countfreq);

if (SCAN != 1 && SCAN != 2)display.print(F("TX: "));

if (SCAN == 1)display.print(F("RX2: "));

if (SCAN != 2)display.println(String(TXFREQ, 4) + POWERTXT);

display.setCursor(0, 17);

display.print(String("SQ: ") + String(SQ));

display.setCursor(67, 17);

if (SCAN != 2 && SCAN != 1)display.print(String("CTCSS: ") + String(CTCSS));

display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);

display.setCursor(0, 25); display.print(String(active));


if (count == 1 || count == 2)

{

if (MHZ == 3)display.print(String(" 10M"));

if (MHZ == 2)display.print(String(" 1M"));

if (MHZ == 1)display.print(String(" 100k"));

if (MHZ == 0)display.print(String(" 12.5k"));

}

if ((count == 2) && (MHZ == 4))display.print(String(" POWER"));

if ((count == 1) && (MHZ == 4))display.print(String(" CTCSS"));

if (count == 3)

{

if (SCAN == 0)display.print(String(" / MEM OFF >"));

if (SCAN == 1)display.print(String(" < SCAN ON >"));

if (SCAN == 2)display.print(String(" < MSCAN >"));

if (SCAN == 3)display.print(String(" < MEM >"));

if ((SCAN >= 4) && (SCAN <= 9))display.print(String(" < STORE ") + (SCAN - 4) + (" >"));

}


if ((count == 2) && (MHZ == 5) && RXTX == 1)display.print(String(" TX=RX"));

if ((count == 2) && (MHZ == 5) && RXTX == 0)display.print(String(" TX=TX"));


display.setTextColor(SSD1306_WHITE); // Draw white text

if (count == 0)

{

display.print(String(" ") + String(VOL));

display.setCursor(45, 25);


if (SCAN == 3)

{

display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);

display.print(String(" MEM ") + String(countmem));

display.setTextColor(SSD1306_WHITE);

}


if (SCAN == 1 || SCAN == 2) //Fscan/Mscan

{

display.setCursor(75, 24);

display.print(freq, 4);

display.drawRect(72, 22, 55, 10, SSD1306_WHITE);//Rektangel runt frekvens

}

}

display.setCursor(85, 25);


if ((count == 6) && SAVE == 0)display.print(String("NEXT->"));

if ((count == 6) && SAVE == 1)display.print(String(" SAVE"));

if ((count == 0) && SCAN == 0)display.print(String(CTEXT));

display.display();


}//End Disp

UHF variant 400-470 MHz ver.1.1

//HAM kit v.1.1 UHF 210118

/* Arduino NANO

Sketch uses 30658 bytes (99%) of program storage space. Maximum is 30720 bytes.

Global variables use 1046 bytes (51%) of dynamic memory, leaving 1002 bytes for local variables. Maximum is 2048 bytes.

V.1.1: Scanner ändrad. CTCSS frekvensvisning borttagen. Buggfix EEPROM.

*/

//RADIO

#include <stdio.h>

#include <SoftwareSerial.h>

#include "DRA818.h"

#include <EEPROM.h>

#define RX 3 // arduino serial RX pin to the DRA818 TX pin

#define TX 4 // arduino serial TX pin to the DRA818 RX pin

int BUTTON = 2;

float TIMEBUTTON;//Tid för långtryck på BUTTON

int count;

float stime;

float xx;

float RXFREQ = 434.6500;//RX Startfrekvens (MHz)(Om EEPROM är tomt)

float TXFREQ = 432.6500;//TX Startfrekvens (MHz)

int SCAN;

float freq = RXFREQ;//Scannerfrekvens

uint8_t SQ = 1; //Squelch vid start (0-8)

uint8_t VOL = 4; //Ljudvolym vid start (1-8)

uint8_t CTCSS = 16; //CTCSS kanal vid start (0-38)

uint8_t CTCSSRX;

int MEM; //Menu memory

float timerR;

float timerT;

float TIMEOUT;

String active;

String CTEXT;//Text för CTCSS

int MHZ;

int SAVE;

int eeAddress;

int POWER = 1;

int TONE;

int RXTX;


struct MyObject { //Data som Sparas/Läses från EEPROM

float fieldRX;//RXFREQ

float fieldTX;//TXFREQ

int fieldSQ;

int fieldVOL;

uint8_t fieldCTCSS;

double fieldF0;//RX Minne 0-5...

double fieldF1;

double fieldF2;

double fieldF3;

double fieldF4;

double fieldF5;

double fieldT0;//TX Minne 0-5...

double fieldT1;

double fieldT2;

double fieldT3;

double fieldT4;

double fieldT5;

uint8_t fieldCTCSS0;//CTCSS Minne 0-5...

uint8_t fieldCTCSS1;

uint8_t fieldCTCSS2;

uint8_t fieldCTCSS3;

uint8_t fieldCTCSS4;

uint8_t fieldCTCSS5;

};

SoftwareSerial *dra_serial; // Serial connection to DRA818

DRA818 *dra; // the DRA object once instanciated


double myRX[] = {4346000, 4346500, 4347000, 4347250, 4340000, 4215625}; //RX lista (MHZ*10000)

double myTX[] = {4326000, 4326500, 4327000, 4327250, 4340000, 4215625}; //TX lista

uint8_t myCTCSS[] = {16, 16, 16, 0, 0, 0}; //CTCSS kanallista

int countfreq;//Scanminne

int countmem;//Kanalminne

int pausescan;//Detekterad kanal


//DISPLAY

#include <SPI.h>

#include <Wire.h>

#include <Adafruit_GFX.h>

#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels

#define SCREEN_HEIGHT 32 // OLED display height, in pixels

#define OLED_RESET -1 // Reset pin #

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);



void configure() //Starta upp radio med inställningar

{

dra = new DRA818(dra_serial, DRA818_UHF);

dra->handshake();

dra->group(DRA818_12K5, RXFREQ, TXFREQ, CTCSS, SQ, CTCSSRX);

dra->volume(VOL);

dra->filters(true, true, true);

}


void NEXT() //Nästa menyval

{

TIMEOUT = millis();

timerR = millis();

count++;

MEM = 0;

MHZ = 0;

TIMEBUTTON = millis();

SCAN = 0;

xx = millis();

}


void saving() //Spara inställningar

{

display.clearDisplay();

display.setTextSize(1); // Normal 1:1 pixel scale

display.setTextColor(SSD1306_WHITE); // Draw white text

display.setCursor(35, 12);

if (SCAN > 3)display.print(F("Saved"));

if (SAVE == 1)display.print(F("EEPROM"));

display.display();

delay(500);

}


void setup() {


Serial.begin(9600);

dra_serial = new SoftwareSerial(RX, TX); // Instantiate the Software Serial Object.


//DISP:


if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32

// Serial.println(F("SSD1306 allocation failed"));

for (;;); // Don't proceed, loop forever

}


display.clearDisplay();

display.setTextSize(1); // Normal 1:1 pixel scale

display.setTextColor(SSD1306_WHITE); // Draw white text

display.setCursor(35, 12); // Startuptext position

display.print(F("HAM kit v.1.1")); //Startuptext

display.display();

delay(500); //Tid som startuptext visas (ms)

//configure();


display.clearDisplay();// Clear the buffer


timerR = millis();

timerT = millis();

pinMode(13, OUTPUT); //Styrning uteffekt H/L

pinMode(BUTTON, INPUT_PULLUP); //Tryckknapp

pinMode(5, INPUT_PULLUP); //VredNER,10-11

pinMode(6, INPUT_PULLUP); //VredUPP, 11-10

digitalWrite(13, POWER); //Sätt utefekt

pinMode(8, OUTPUT); //Ljudförstärkarutgång

pinMode(7, INPUT); //Vid radiosignal, aktivera ljudförstärkarutgång

// pinMode(12, OUTPUT); //Aktivera sändning

//digitalWrite(12, 0); //Sätt utefekt

MyObject customVar; //Variable to store custom object read from EEPROM.

EEPROM.get( eeAddress, customVar );//Läs från EEPROM:

if(customVar.fieldRX>100)//Kontrollera att EEPROM inte är tomt innan inläsning

{

RXFREQ = customVar.fieldRX; //RX Startfrekvens

TXFREQ = customVar.fieldTX; //TX Startfrekvens

SQ = customVar.fieldSQ; //Squelch start

VOL = customVar.fieldVOL; //Ljudvolym start

CTCSS = customVar.fieldCTCSS; //CTCSS start

myRX[0] = customVar.fieldF0; //RX frekvens lista 0-5...

myRX[1] = customVar.fieldF1;

myRX[2] = customVar.fieldF2;

myRX[3] = customVar.fieldF3;

myRX[4] = customVar.fieldF4;

myRX[5] = customVar.fieldF5;

myTX[0] = customVar.fieldT0; //TX frekvens lista 0-5...

myTX[1] = customVar.fieldT1;

myTX[2] = customVar.fieldT2;

myTX[3] = customVar.fieldT3;

myTX[4] = customVar.fieldT4;

myTX[5] = customVar.fieldT5;

myCTCSS[0] = customVar.fieldCTCSS0;//CTCSS lista 0-5...

myCTCSS[1] = customVar.fieldCTCSS1;

myCTCSS[2] = customVar.fieldCTCSS2;

myCTCSS[3] = customVar.fieldCTCSS3;

myCTCSS[4] = customVar.fieldCTCSS4;

myCTCSS[5] = customVar.fieldCTCSS5;

}

configure();

}



void loop() {


if (digitalRead(7) == 0 && VOL != 0) //Vid radiosignal, aktivera ljud

{

digitalWrite(8, HIGH);

}

else digitalWrite(8, LOW);


if (!dra) return; // do nothing if DRA configuration failed


if (digitalRead(BUTTON) != 0)

{

TIMEBUTTON = millis();

}


if (count == 0)active = "VOL"; //VOLMENU

if (count == 1)active = "RX"; //RXMENU

if (count == 2)active = "TX"; //TXMENU

if (count == 3)active = "SCAN"; //SCANMENU

if (count == 4)active = "SQ"; //SQMENU

if (count == 5)active = "CTCSS"; //CTCSSMENU

if (count == 6)active = "EEPROM"; //EEPROMMENU


if (MEM == 0)

{

disp();

MEM = 1;

}


if (digitalRead(5) == 0 && digitalRead(6) == 1 && ((millis() - timerR) > 20)) //Vid vridning moturs (50 ms)

{

TIMEOUT = millis();


if (count == 0) //VOLMENU

{

if (SCAN != 3)

{

VOL -= 1;

if ((VOL < 0) || (VOL > 8))VOL = 0;

if (VOL > 0)dra->volume(VOL);

}

if (SCAN == 3)

{

countmem--;

if (countmem < 0)countmem = 5;

RXFREQ = (float)myRX[countmem] / 10000; //Läs i listan

TXFREQ = (float)myTX[countmem] / 10000;

CTCSS = myCTCSS[countmem];

dra->group(DRA818_12K5, RXFREQ, TXFREQ, CTCSS, SQ, CTCSSRX);

}

MEM = 0;

}


if (count == 1) //RXMENU

{

double FR = (RXFREQ * 10000);

if (MHZ == 0)FR -= 125; //12.5kHz step

if (MHZ == 1)FR -= 1000;

if (MHZ == 2)FR -= 10000;

if (MHZ == 3)FR -= 100000;

RXFREQ = (float)(FR / 10000), 4;

if (MHZ == 4)TONE = 0;

if (TONE == 0)CTCSSRX = 0;

if (RXTX == 1)TXFREQ = RXFREQ;

MEM = 0;

dra->group(DRA818_12K5, RXFREQ, TXFREQ, CTCSS, SQ, CTCSSRX);

}


if (count == 2) //TXMENU

{

double FT = (TXFREQ * 10000);

if (MHZ == 0)FT -= 125; //12.5kHz step

if (MHZ == 1)FT -= 1000;

if (MHZ == 2)FT -= 10000;

if (MHZ == 3)FT -= 100000;

TXFREQ = (float)(FT / 10000), 4;

if (MHZ == 4)POWER = 1;

if (MHZ == 5)RXTX = 0;

MEM = 0;

dra->group(DRA818_12K5, RXFREQ, TXFREQ, CTCSS, SQ, CTCSSRX);

}

if (count == 3) //SCANMENU

{

SCAN -= 1;

if (SCAN < 0)SCAN = 0;

MEM = 0;

}


if (count == 4)//SQMENU

{

SQ -= 1;

if ((SQ < 0) || (SQ > 8))SQ = 0;

MEM = 0;

dra->group(DRA818_12K5, RXFREQ, TXFREQ, CTCSS, SQ, CTCSSRX);

}


if (count == 5)//CTCSSMENU

{

CTCSS -= 1;

if (CTCSS < 0 || CTCSS == 255)CTCSS = 38; //38

if (TONE == 1)CTCSSRX = CTCSS;

MEM = 0;

dra->group(DRA818_12K5, RXFREQ, TXFREQ, CTCSS, SQ, CTCSSRX);

}

if (count == 6)//EEPROMMENU

{

SAVE -= 1;

if (SAVE < 0)SAVE = 1;

MEM = 0;

}

timerR = millis();

}


if (digitalRead(5) == 0 && digitalRead(6) == 0 && ((millis() - timerR) > 20)) //Vid vridning medurs (50 ms)

{

TIMEOUT = millis();

if (count == 0) //VOLMENU

{

if (SCAN != 3)

{

VOL += 1;

if (VOL > 8)VOL = 8;

dra->volume(VOL);

}

if (SCAN == 3)

{

countmem++;

if (countmem > 5)countmem = 0;

RXFREQ = (float)myRX[countmem] / 10000; //Läs i listan

TXFREQ = (float)myTX[countmem] / 10000;

CTCSS = myCTCSS[countmem];

dra->group(DRA818_12K5, RXFREQ, TXFREQ, CTCSS, SQ, CTCSSRX);

}

MEM = 0;

}


if (count == 1) //RXMENU

{

double FR = (RXFREQ * 10000);

if (MHZ == 0)FR += 125; //12.5kHz step

if (MHZ == 1)FR += 1000;

if (MHZ == 2)FR += 10000;

if (MHZ == 3)FR += 100000;

RXFREQ = (float)(FR / 10000), 4;

if (MHZ == 4)TONE = 1;

if (TONE == 1)CTCSSRX = CTCSS;

if (RXTX == 1)TXFREQ = RXFREQ;

MEM = 0;

dra->group(DRA818_12K5, RXFREQ, TXFREQ, CTCSS, SQ, CTCSSRX);

}


if (count == 2)//TXMENU

{

double FT = (TXFREQ * 10000);

if (MHZ == 0)FT += 125; //12.5kHz step

if (MHZ == 1)FT += 1000;

if (MHZ == 2)FT += 10000;

if (MHZ == 3)FT += 100000;

TXFREQ = (float)(FT / 10000), 4;

if (MHZ == 4)POWER = 0;

if (MHZ == 5)RXTX = 1;

MEM = 0;

dra->group(DRA818_12K5, RXFREQ, TXFREQ, CTCSS, SQ, CTCSSRX);

}

if (count == 3) //SCANMENU

{

SCAN += 1;

if (SCAN > 9)SCAN = 0;

MEM = 0;

}

if (count == 4)//SQMENU

{

SQ += 1;

if (SQ > 8)SQ = 0;

MEM = 0;

dra->group(DRA818_12K5, RXFREQ, TXFREQ, CTCSS, SQ, CTCSSRX);

}


if (count == 5)//CTCSSMENU

{

CTCSS += 1;

if (CTCSS > 38)CTCSS = 0; //38 max

if (TONE == 1)CTCSSRX = CTCSS;

MEM = 0;

dra->group(DRA818_12K5, RXFREQ, TXFREQ, CTCSS, SQ, CTCSSRX);

}


if (count == 6)//EEPROMMENU

{

SAVE += 1;

if (SAVE > 1)SAVE = 0;

MEM = 0;

}

timerR = millis();

}


if (count == 1 || count == 2) //RX eller TX

{

if ((digitalRead(BUTTON) == 0) && (millis() - timerT > 500)) //Stega MHz...

{

timerT = millis();

TIMEOUT = millis();

}

if ((millis() - timerT < 399) && ((millis() - xx) > 1200))

{

MHZ++;

if (count == 1 && MHZ > 4)MHZ = 0; //RX

if (MHZ > 5)MHZ = 0;

MEM = 0;

delay(500);

}


}


if ((digitalRead(BUTTON) == 0) && (millis() - TIMEBUTTON) > 1000)

{

NEXT();

digitalWrite(13, POWER); //Sätt uteffekt

if (RXTX == 1)TXFREQ = RXFREQ;

MHZ = 0;

if (SAVE == 1) //Spara i EEPROM?

{

MyObject customVar = {

RXFREQ,

TXFREQ,

SQ,

VOL,

CTCSS,

myRX[0], myRX[1], myRX[2], myRX[3], myRX[4], myRX[5],

myTX[0], myTX[1], myTX[2], myTX[3], myTX[4], myTX[5],

myCTCSS[0], myCTCSS[1], myCTCSS[2], myCTCSS[3], myCTCSS[4], myCTCSS[5]

};

eeAddress = 0;

EEPROM.put(eeAddress, customVar);

saving();

SAVE = 0;

}

}


if (((millis() - TIMEOUT) > 3000) && count != 0)//Vid 3s inaktivitet.

{

count = 0;

MEM = 0;

SAVE = 0;

if (RXTX == 1)TXFREQ = RXFREQ;

digitalWrite(13, POWER); //Sätt utefekt


if (SCAN > 3)

{

myRX[SCAN - 4] = (double)RXFREQ * 10000; //Lagra i listan

myTX[SCAN - 4] = (double)TXFREQ * 10000;

myCTCSS[SCAN - 4] = CTCSS;

saving();

SCAN = 0;

}

dra->group(DRA818_12K5, RXFREQ, TXFREQ, CTCSS, SQ, CTCSSRX);

}//


if (count > 6)count = 0; //Efter sista menyn, gå till meny 0.

if (TXFREQ > DRA818_UHF_MAX) TXFREQ = DRA818_UHF_MIN; // when DRA818_UHF_MAX (470.0) is reached, start over at DRA818_UHF_MIN (400.0)

if (TXFREQ < DRA818_UHF_MIN) TXFREQ = DRA818_UHF_MAX;

if (RXFREQ > DRA818_UHF_MAX) RXFREQ = DRA818_UHF_MIN; // when DRA818_UHF_MAX (470.0) is reached, start over at DRA818_UHF_MIN (400.0)

if (RXFREQ < DRA818_UHF_MIN) RXFREQ = DRA818_UHF_MAX;


if (SCAN > 0 && SCAN < 3 && count == 0)SCANNER();


}//Loop



void SCANNER()

{

int nostore = 0;


if (digitalRead(BUTTON) == 0)goto quit;//Gå till nästa kanal vid tryck

if (pausescan == 0 )//&& digitalRead(7) == 1)

{

if (dra->scan(freq))

{

pausescan = 1;

dra->group(DRA818_12K5, freq, TXFREQ, CTCSS, SQ, CTCSSRX);

stime = millis();


if (SCAN == 1)

{

for (int i = 0; i < 5; i++)

{

if ((float)(myRX[i] / 10000) == freq)nostore = 1;

}

if (nostore != 1)

{

myRX[countfreq] = myTX[countfreq] = (double)freq * 10000; //Lagra i listan

countfreq++;

if (countfreq > 5)countfreq = 0;

}

}


}


}//End pausescan


if ((millis() - stime) > 5000)//Om 5 sek har gått, sök vidare

{

quit:

if (SCAN == 1)

{

double FRE = (freq * 10000); //Gör om till double för bättre precision

if (TXFREQ > RXFREQ)

{

FRE += 125; //12.5kHz step

freq = (float)(FRE / 10000), 4;

if (freq > TXFREQ) freq = RXFREQ;

// if (freq < RXFREQ) freq = TXFREQ;

}

if (TXFREQ < RXFREQ)

{

FRE -= 125; //12.5kHz step

freq = (float)(FRE / 10000), 4;

if (freq < TXFREQ) freq = RXFREQ;

// if (freq > RXFREQ) freq = TXFREQ;

}

pausescan=0;

}


if (SCAN == 2 && pausescan == 0 && digitalRead(7) == 1)//Om signal ej är kvar, sök vidare, annars vänta

{

countfreq++;

if (countfreq > 5)countfreq = 0;

if (myRX[countfreq] >= DRA818_VHF_MIN)freq = (myRX[countfreq] / 10000);

}

if(digitalRead(7) == 1)pausescan = 0;

disp();

}


}//End scanner


void disp() //Visa i display

{

display.clearDisplay();

display.setTextSize(1); // Normal 1:1 pixel scale

display.setTextColor(SSD1306_WHITE); // Draw white text

display.setCursor(0, 0); // Start at top-left corner

String POWERTXT;

String TONETEXT;

if (POWER == 0)POWERTXT = " MHz H";

if (POWER == 1)POWERTXT = " MHz L";

if (TONE == 0)TONETEXT = " MHz ";

if (TONE == 1)TONETEXT = " MHz T";


if (SCAN != 1)display.print(F("RX: "));

if (SCAN == 1)display.print(F("RX1: "));

if (SCAN != 2)display.println(String(RXFREQ, 4) + TONETEXT);

if (SCAN == 2)display.println(String("MEM ") + countfreq);

if (SCAN != 1 && SCAN != 2)display.print(F("TX: "));

if (SCAN == 1)display.print(F("RX2: "));

if (SCAN != 2)display.println(String(TXFREQ, 4) + POWERTXT);

display.setCursor(0, 17);

display.print(String("SQ: ") + String(SQ));

display.setCursor(67, 17);

if (SCAN != 2 && SCAN != 1)display.print(String("CTCSS: ") + String(CTCSS));

display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);

display.setCursor(0, 25); display.print(String(active));


if (count == 1 || count == 2)

{

if (MHZ == 3)display.print(String(" 10M"));

if (MHZ == 2)display.print(String(" 1M"));

if (MHZ == 1)display.print(String(" 100k"));

if (MHZ == 0)display.print(String(" 12.5k"));

}

if ((count == 2) && (MHZ == 4))display.print(String(" POWER"));

if ((count == 1) && (MHZ == 4))display.print(String(" CTCSS"));

if (count == 3)

{

if (SCAN == 0)display.print(String(" / MEM OFF >"));

if (SCAN == 1)display.print(String(" < SCAN ON >"));

if (SCAN == 2)display.print(String(" < MSCAN >"));

if (SCAN == 3)display.print(String(" < MEM >"));

if ((SCAN >= 4) && (SCAN <= 9))display.print(String(" < STORE ") + (SCAN - 4) + (" >"));

}


if ((count == 2) && (MHZ == 5) && RXTX == 1)display.print(String(" TX=RX"));

if ((count == 2) && (MHZ == 5) && RXTX == 0)display.print(String(" TX=TX"));


display.setTextColor(SSD1306_WHITE); // Draw white text

if (count == 0)

{

display.print(String(" ") + String(VOL));

display.setCursor(45, 25);


if (SCAN == 3)

{

display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);

display.print(String(" MEM ") + String(countmem));

display.setTextColor(SSD1306_WHITE);

}


if (SCAN == 1 || SCAN == 2) //Fscan/Mscan

{

display.setCursor(75, 24);

display.print(freq, 4);

display.drawRect(72, 22, 55, 10, SSD1306_WHITE);//Rektangel runt frekvens

}

}

display.setCursor(85, 25);


if ((count == 6) && SAVE == 0)display.print(String("NEXT->"));

if ((count == 6) && SAVE == 1)display.print(String(" SAVE"));

if ((count == 0) && SCAN == 0)display.print(String(CTEXT));

display.display();


}//End Disp

Programexempel VHF

Här är en lite enklare och förkortad VHF programversion med fler kommentarer i koden. Koden är gjord som exempel.

Grundinställningar står med fet stil i koden.

  • Sändar- och mottagarfrekvens är här densamma.

  • Frekvens visas med större text i displayen.

  • Endast ljudvolym och frekvens kan ändras med vredet.

  • Det är ej möjligt att scanna eller spara i EEPROM.

  • Ingen kanallista finns.


Programkod:


//HAM kit v.1.0 VHF EXEMPEL

/* Arduino NANO

Sketch uses 23692 bytes (77%) of program storage space. Maximum is 30720 bytes.

Global variables use 783 bytes (38%) of dynamic memory, leaving 1265 bytes for local variables. Maximum is 2048 bytes.

*/

//RADIO

#include <stdio.h>

#include <SoftwareSerial.h>

#include "DRA818.h"

#define RX 3 // arduino serial RX pin to the DRA818 TX pin

#define TX 4 // arduino serial TX pin to the DRA818 RX pin

int BUTTON = 2;

float TIMEBUTTON;//Tid för långtryck på BUTTON

int count; //Menyräknare

float xx;

//Grundinställningar:

float RXFREQ = 145.2500;//RX Startfrekvens (MHz)

float TXFREQ = RXFREQ; //TX Startfrekvens (MHz)

uint8_t SQ = 1; //Squelch (0-8)

uint8_t VOL = 4; //Ljudvolym vid uppstart (1-8)

uint8_t CTCSS = 0; //CTCSS kanal (0-38)

int POWER = 1;//Uteffekt. 1=Låg. 0=Hög.


int MEM; //Menu memory (Håller koll på om meny är aktiv)

float timerR;

float timerT;

float TIMEOUT;

String active;

int MHZ;

int SAVE;



SoftwareSerial *dra_serial; // Serial connection to DRA818

DRA818 *dra; // the DRA object once instanciated


//DISPLAY

#include <SPI.h>

#include <Wire.h>

#include <Adafruit_GFX.h>

#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels

#define SCREEN_HEIGHT 32 // OLED display height, in pixels

#define OLED_RESET -1 // Reset pin #

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);



void configure() //Starta upp radio med inställningar

{

dra = new DRA818(dra_serial, DRA818_VHF);

dra->handshake();

dra->group(DRA818_12K5, RXFREQ, TXFREQ, CTCSS, SQ, CTCSS);

dra->volume(VOL);

dra->filters(true, true, true);

}


void NEXT() //Nästa menyval

{

TIMEOUT = millis();

timerR = millis();

count++;

MEM = 0;

MHZ = 0;

TIMEBUTTON = millis();

xx = millis();

}


void setup() {


Serial.begin(9600);

dra_serial = new SoftwareSerial(RX, TX); // Instantiate the Software Serial Object.


//DISP:


if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32

// Serial.println(F("SSD1306 allocation failed"));

for (;;); // Don't proceed, loop forever

}


display.clearDisplay();

display.setTextSize(1); // Normal 1:1 pixel scale

display.setTextColor(SSD1306_WHITE); // Draw white text

display.setCursor(35, 8); // Startuptext 1 position

display.println(F("HAM kit VHF Ex.")); //Startuptext 1

display.display();

delay(500); //Tid som startuptext visas (ms)

configure();

if (!dra) {

// Serial.println("\nError while configuring DRA818");

}

display.clearDisplay();// Clear the buffer


timerR = millis();

timerT = millis();

pinMode(13, OUTPUT); //Styrning uteffekt H/L

pinMode(BUTTON, INPUT_PULLUP); //Tryckknapp

pinMode(5, INPUT_PULLUP); //VredNER,10-11

pinMode(6, INPUT_PULLUP); //VredUPP, 11-10

digitalWrite(13, POWER); //Sätt utefekt

pinMode(8, OUTPUT); //Ljudförstärkarutgång

pinMode(7, INPUT); //Vid radiosignal, aktivera ljudförstärkarutgång

}



void loop() {


if (digitalRead(7) == 0 && VOL != 0) //Vid radiosignal, aktivera ljud

{

digitalWrite(8, HIGH);

}

else digitalWrite(8, LOW);


if (!dra) return; // do nothing if DRA configuration failed


if (digitalRead(BUTTON) != 0)

{

TIMEBUTTON = millis();

}


if (count == 0)active = "VOL"; //VOLMENU

if (count == 1)active = "FREQ"; //RXMENU


if (MEM == 0)

{

disp();

MEM = 1;

}

if (digitalRead(5) == 0 && digitalRead(6) == 1 && ((millis() - timerR) > 20)) //Vid vridning moturs (20 ms)

{

TIMEOUT = millis();


if (count == 0) //VOLMENU

{

VOL -= 1;

if ((VOL < 0) || (VOL > 8))VOL = 0;

if (VOL > 0)dra->volume(VOL);

MEM = 0;

}


if (count == 1) //Frekvensmeny

{

double FR = (RXFREQ * 10000);

if (MHZ == 0)FR -= 125; //12.5kHz step

if (MHZ == 1)FR -= 1000;

if (MHZ == 2)FR -= 10000;

if (MHZ == 3)FR -= 100000;

RXFREQ = (float)(FR / 10000), 4;

TXFREQ = RXFREQ;

dra->group(DRA818_12K5, RXFREQ, TXFREQ, CTCSS, SQ, CTCSS);

MEM = 0;

}


timerR = millis();

}


if (digitalRead(5) == 0 && digitalRead(6) == 0 && ((millis() - timerR) > 20)) //Vid vridning medurs (20 ms)

{

TIMEOUT = millis();

if (count == 0) //VOLMENU

{

VOL += 1;

if (VOL > 8)VOL = 8;

dra->volume(VOL);

MEM = 0;

}


if (count == 1) //Frekvensmeny

{

double FR = (RXFREQ * 10000);

if (MHZ == 0)FR += 125; //12.5kHz step

if (MHZ == 1)FR += 1000;

if (MHZ == 2)FR += 10000;

if (MHZ == 3)FR += 100000;

RXFREQ = (float)(FR / 10000), 4;

TXFREQ = RXFREQ;

MEM = 0;

dra->group(DRA818_12K5, RXFREQ, TXFREQ, CTCSS, SQ, CTCSS);

}


timerR = millis();

}


if (count == 1) //Frekvensmeny

{

if ((digitalRead(BUTTON) == 0) && (millis() - timerT > 500)) //Stega MHz...

{

timerT = millis();

TIMEOUT = millis();

}

if ((millis() - timerT < 399) && ((millis() - xx) > 1200))

{

MHZ++;

if (MHZ > 3)MHZ = 0;//Efter 10MHz, välj 12,5kHz

MEM = 0;

delay(500);

}


}


if ((digitalRead(BUTTON) == 0) && (millis() - TIMEBUTTON) > 1000)//Vid 1s.tryck på knapp

{

NEXT();

MHZ = 0;

}

if (((millis() - TIMEOUT) > 3000) && count != 0)//Vid 3s inaktivitet.

{

count = 0;

MEM = 0;

}

if (count > 1)count = 0; //Efter sista menyn, gå till meny 0.

if (TXFREQ > DRA818_VHF_MAX) TXFREQ = DRA818_VHF_MIN; // when DRA818_VHF_MAX (174.0) is reached, start over at DRA818_VHF_MIN (134.0)

if (TXFREQ < DRA818_VHF_MIN) TXFREQ = DRA818_VHF_MAX;

if (RXFREQ > DRA818_VHF_MAX) RXFREQ = DRA818_VHF_MIN; // when DRA818_VHF_MAX (174.0) is reached, start over at DRA818_VHF_MIN (134.0)

if (RXFREQ < DRA818_VHF_MIN) RXFREQ = DRA818_VHF_MAX;


}//Loop



void disp() //Visa i display

{

display.clearDisplay();

display.setTextSize(2); // Big 2:2 pixel scale

display.setTextColor(SSD1306_WHITE); // Draw white text

display.setCursor(0, 0); // Start at top-left corner

display.print(String(RXFREQ, 4));

display.setTextSize(1); // Normal 1:1 pixel scale

display.print(String(" MHz"));

display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);

display.setCursor(0, 25);

display.print(String(active));


if (count == 1)

{

if (MHZ == 3)display.print(String(" 10M"));

if (MHZ == 2)display.print(String(" 1M"));

if (MHZ == 1)display.print(String(" 100k"));

if (MHZ == 0)display.print(String(" 12.5k"));

}



display.setTextColor(SSD1306_WHITE); // Draw white text

if (count == 0)

{

display.print(String(" ") + String(VOL));

}


display.display();


}//End Disp

Programexempel UHF

Här är en UHF scanner som styrs med endast tryckknappen. Vid uppstart väljs en TX , RX frekvens och CTCSS, men efter ett tryck
på knappen hoppar den till kanallistan. Sedan vid varje tryck (1 s.) växlar den mellan att scanna hela kanallistan eller stega mellan kanalerna. Stegning görs med korta tryck.

Inställningar såsom frekvenser, ljudvolym och squelch är fasta. -Ljudvolymen kan ju alltid justeras med potentiometern.

I exemplet är 12 kanaler inlagda i RX listan, men upp till 99 kan läggas in.

  • Sändar- och mottagarfrekvens är här densamma förutom vid uppstart.

  • Frekvens visas med större text i displayen.

  • Inställningar görs i programkoden.

  • Det är ej möjligt att spara i EEPROM.

  • Denna scanner är ljudlös vid scanning (Inget brus hörs vid frekvensbyte).



Programkod:


//MiniRF v.1.0 UHF

/*

Sketch uses 22446 bytes (73%) of program storage space. Maximum is 30720 bytes.

Global variables use 825 bytes (40%) of dynamic memory, leaving 1223 bytes for local variables. Maximum is 2048 bytes.

*/


//RADIO

#include <stdio.h>

#include <SoftwareSerial.h>

#include "DRA818.h"

#define RX 3 // arduino serial RX pin to the DRA818 TX pin

#define TX 4 // arduino serial TX pin to the DRA818 RX pin

int BUTTON = 2;

float TIMEBUTTON;//Tid för långtryck på BUTTON

int count;

int SCAN;

float stime;


float RXFREQ = 434.6500;//RX Startfrekvens (MHz)

float TXFREQ = 432.6500;//TX Startfrekvens (MHz)

uint8_t SQ = 2; //Squelch vid start (0-8)

uint8_t VOL = 8; //Ljudvolym vid start (1-8)

uint8_t CTCSS = 16; //CTCSS kanal vid start (0-38)

uint8_t CTCSSRX;

int POWER = 1; //Uteffekt. 0=Hög 1=Låg.

int MEM; //Menu memory

float timerR;

float TIMEOUT;

int noofchan=12; //Antal kanaler som används i RX listan (Nu 12 men kan fyllas på med max 99)

SoftwareSerial *dra_serial; // Serial connection to DRA818

DRA818 *dra; // the DRA object once instanciated


double myRX[] = {4460063, 4460188,4460313, 4460438, 4460563, 4460688, 4460813, 4460938, 4346000, 4346500, 4346875, 4215625}; //RX lista (MHZ*10000)


/*

PMR kanaler:

Kanal 1 – 446,00625 MHz

Kanal 2 – 446,01875 MHz

Kanal 3 – 446,03125 MHz

Kanal 4 – 446,04375 MHz

Kanal 5 – 446,05625 MHz

Kanal 6 – 446,06875 MHz

Kanal 7 – 446,08125 MHz

Kanal 8 – 446,09375 MHz

*/

int countfreq;//Scanminne

int countmem=-1;//Kanalminne

int pausescan;//Detekterad kanal



//DISPLAY

#include <SPI.h>

#include <Wire.h>

#include <Adafruit_GFX.h>

#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels

#define SCREEN_HEIGHT 32 // OLED display height, in pixels

#define OLED_RESET -1 // Reset pin #

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);



void configure() //Starta upp radio med inställningar

{

dra = new DRA818(dra_serial, DRA818_UHF);

dra->handshake();

dra->group(DRA818_12K5, RXFREQ, TXFREQ, CTCSS, SQ, CTCSSRX);

dra->volume(VOL);

dra->filters(true, true, true);

}


void NEXT() //Nästa menyval

{

TIMEOUT = millis();

timerR = millis();

count++;

MEM = 0;

TIMEBUTTON = millis();

if(count==1)

{

SCAN=1;

}

else SCAN=0;

}


void senddata()

{

countmem++;

if (countmem > noofchan-1)countmem = 0;

RXFREQ = (float)myRX[countmem] / 10000; //Läs i listan

TXFREQ = RXFREQ;

dra->group(DRA818_12K5, RXFREQ, TXFREQ, CTCSS, SQ, CTCSSRX);

}


void setup() {


Serial.begin(9600);

dra_serial = new SoftwareSerial(RX, TX); // Instantiate the Software Serial Object.


configure();

if (!dra) {

Serial.println("\nError while configuring DRA818");

}


timerR = millis();

pinMode(BUTTON, INPUT_PULLUP); //Tryckknapp

pinMode(7, INPUT); //Signal

pinMode(8, OUTPUT); //Ljudförstärkarutgång

pinMode(13, OUTPUT); //Styrning uteffekt H/L

digitalWrite(13, POWER); //Sätt uteffekt

//DISP:


if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32

Serial.println(F("SSD1306 allocation failed"));

for (;;); // Don't proceed, loop forever

}

display.clearDisplay();

display.setTextSize(1); // Normal 1:1 pixel scale

display.setTextColor(SSD1306_WHITE); // Draw white text

display.setCursor(30, 8); // Startuptext 1 position

display.println(F("HAM kit UHF RX")); //Startuptext 1

display.display();

delay(500); //Tid som startuptext visas (ms)

display.clearDisplay();// Clear the buffer

}




void loop() {



if (!dra) return; // do nothing if DRA configuration failed


if (digitalRead(7) == 0) //Vid radiosignal, aktivera ljud

{

digitalWrite(8, HIGH);

}

else digitalWrite(8, LOW);


if (digitalRead(BUTTON) != 0)

{

TIMEBUTTON = millis();

}



if (MEM == 0)

{

disp();

MEM = 1;

}


if (digitalRead(BUTTON) == 0 && ((millis() - timerR) > 60)) //Vid tryck på knappen (60 ms)

{

TIMEOUT = millis();

if (count == 0) //VOLMENU

{

if (SCAN == 0)

{

senddata();

delay(20);

}

MEM = 0;

}


timerR = millis();

}



if ((digitalRead(BUTTON) == 0) && (millis() - TIMEBUTTON) > 1000)//Vid 1s tryck på knappen

{

NEXT();

}


if (count > 1)count = 0; //Efter sista menyn, gå till meny 0.

if (SCAN == 1 && count == 1)SCANNER();


}//Loop



void SCANNER()

{

int nostore = 0;

if (digitalRead(BUTTON) == 0)goto quit;//Gå till nästa kanal vid tryck

if (pausescan == 0 )

{

if (digitalRead(7) == 0)

{

pausescan = 1;

stime = millis();

}


}//End pausescan


if ((millis() - stime) > 5000)//Om 5 sek har gått, sök vidare

{

// quit:


if (SCAN == 1 && pausescan == 0 && digitalRead(7) == 1)//Om signal ej är kvar, sök vidare, annars vänta (7) && pausescan == 0

{

quit:

senddata();

delay(100);

MEM=0;

pausescan = 0;

}

pausescan = 0;

}


}//End scanner



void disp() //Visa i display

{

display.clearDisplay();

display.setTextSize(2,4); // Big 2:2 pixel scale

display.setTextColor(SSD1306_WHITE); // Draw white text

display.setCursor(0, 0); // Start at top-left corner

display.print(String(RXFREQ, 4));

display.setTextSize(1); // Normal 1:1 pixel scale

if(SCAN==0)

{

display.print(String(" MHz"));

if(TXFREQ!=RXFREQ)display.print(String("-")); //Visa "-" om inte TX och RX frekvens är densamma.

}

else display.print(String(" SCAN"));

display.setCursor(100,14);//(110, 14);

display.setTextSize(2,2);

if(countmem==-1) display.print(String(CTCSS)); //Visa CTCSS kanal vid uppstart.

if((countmem+1)<10&&countmem>-1) display.print(String("0"));

if(countmem>-1)display.print(String(countmem+1));

//display.drawRect(107, 12, 16, 18, SSD1306_WHITE);//Rektangel runt kanal 0-9

display.drawRect(98, 12, 26, 18, SSD1306_WHITE);//Rektangel runt kanal 10-99


display.display();


}//End Disp

HÅRDVARA

LJUDFÖRSTÄRKARE:
För att få full spänning till ljudförstärkarkretsen som enligt manual matas med min. 4V, kan ett relä
kopplas in på Arduinons utgång 8 som i sin tur fördelar ut matningsspänningen till kretsens pin 6.
Detta kan vara ett 5V miniatyrrelä som inte tar stor plats och ljudet riskerar då inte att förvrängas om utgångens
spänning blir för låg för att mata förstärkarkretsen.