Mjukvara

Programmet är skrivet i Arduino editor som finns att ladda ner gratis. ( https://www.arduino.cc/en/software)
För att kunna programmera medföljande display och radiomodul, behöver man först installera tilläggen för dem.
Dessa hittar man för nedladdning i editorn och längre ner finns en instruktion för detta.

Här nedan finns koden för både VHF och UHF varianterna. Denna går att kopiera och klistra in i editorn för editering.

För befintlig kod lämnas inga garantier att vara helt buggfri, men radion har testats under lång tid och verkar fungera
som tänkt.

För ändringar och uppdateringar, se fliken Uppdateringar.

VHF variant 134-174 MHz

//HAM kit v.1.0 VHF 210524

/* Arduino NANO

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

Global variables use 1078 bytes (52%) of dynamic memory, leaving 970 bytes for local variables. Maximum is 2048 bytes.

*/

//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;

int SCAN;

float freq;//Scannerfrekvens

float stime;

float xx;

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

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

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.0")); //Startuptext

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


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;

}

freq = RXFREQ; //Startfrekvens scanner

}



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 (20 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 (20 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 (TXFREQ < RXFREQ)

{

FRE -= 125; //12.5kHz step

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

if (freq < TXFREQ) freq = RXFREQ;

}

}


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);

}


disp();

pausescan = 0;

}


}//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 (CTCSS == 0)CTEXT = " off";

if (CTCSS == 15)CTEXT = " 110.9";

if (CTCSS == 16)CTEXT = " 114.8";

if (CTCSS == 17)CTEXT = " 118.8";/*

if (CTCSS == 18)CTEXT = " 123.0";

if (CTCSS == 19)CTEXT = " 127.3";

if (CTCSS == 20)CTEXT = " 131.8";*/

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

//HAM kit v.1.0 UHF 210524

/* Arduino NANO

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

Global variables use 1078 bytes (52%) of dynamic memory, leaving 970 bytes for local variables. Maximum is 2048 bytes.

*/

//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;

int SCAN;

float freq;//Scannerfrekvens

float stime;

float xx;

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

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

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[] = {4246000, 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.0")); //Startuptext

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


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;

}

freq = RXFREQ; //Startfrekvens scanner

}



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 (20 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 (20 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 (TXFREQ < RXFREQ)

{

FRE -= 125; //12.5kHz step

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

if (freq < TXFREQ) freq = RXFREQ;

}

}


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_UHF_MIN)freq = (myRX[countfreq] / 10000);

}


disp();

pausescan = 0;

}


}//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 (CTCSS == 0)CTEXT = " off";

if (CTCSS == 15)CTEXT = " 110.9";

if (CTCSS == 16)CTEXT = " 114.8";

if (CTCSS == 17)CTEXT = " 118.8";/*

if (CTCSS == 18)CTEXT = " 123.0";

if (CTCSS == 19)CTEXT = " 127.3";

if (CTCSS == 20)CTEXT = " 131.8";*/

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

Instruktion för att installera tillägg i Arduino editorn:

För att kunna programmera display och radiodel, behövs följande tillägg installeras i Arduino programvara.
Gå till ”Hantera bibliotek”...


Display: Sök efter ”SSD1306” och installera sedan ”Adafruit SSD1306”...


Radio: Sök även efter ”DRA818” och installera ”DRA818”...


Nu finns exempelfiler att köra och display och radiodel går nu att programmera.