/*
KONTROL ATMEGA8 LCD 1602
122 juli 2024.
"GAPTECH" pUTU ASTRECK
*/
#include <inttypes.h>
#include <LiquidCrystal.h>
#include "SanyoCCB.h"
#include <EEPROM.h>
// LC72131 IN1, byte 0
#define IN10_R3 7
#define IN10_R2 6
#define IN10_R1 5
#define IN10_R0 4
#define IN10_XS 3
#define IN10_DVS 1
#define DO0_UL 4
#define YST93x_BAND_FM 5
#define FM_TUNED_WINDOW 180
enum PinAssignments {
encoderPinA = 1,
encoderPinB = 0,
encoderSwit = 2,//menu
Sql = A3,//ARDUINO UNO
PTT = 13,
VSM = A5,//ARDUIN0 UNO
ST = A4 //ARDUINO UNO
};
volatile int lastEncoded = 0;
volatile long encoderValue = 0;
long lastencoderValue = 0;
int lastMSB = 0;
int lastLSB = 0;
int key = 0;
int sinyal=0;
int agc = 1.2;
int menu1 = 0;
// duplex
//int dup = 0;
int address = 0;
int swPtt = 12;
LiquidCrystal lcd(8, 7, 6, 5, 4, 3); // Pins: RS, E, D4, D5, D6, D7
//LiquidCrystal lcd(3, 4, 5, 6, 7, 8); //PIN VERSI LCD DI BALIK (VERSI B)
void writeWord(int address, int FMFrequency) {
EEPROM.write(address, highByte(FMFrequency));
EEPROM.write(address + 1, lowByte(FMFrequency));
}
unsigned int readWord(int address) {
return word(EEPROM.read(address), EEPROM.read(address + 1));
}
int bandM = readWord(42);
int Step = readWord(44);
//int RfPwr = readWord(46);
int8_t delta = 0;
// memory
int addressN = readWord(40);
int space [] = { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18};
//int duplex[] = {20, 22, 24, 26, 28, 30, 32, 34, 36, 38};
int urutan = 9;
int alamat = readWord(40);
//SanyoCCB ccb(A1, A2, A3, A0); // Pins: DI CL DO CE >> versi asli
//SanyoCCB ccb(A1, A2, A3, A0); // Pins pada ic LC72131: DI(4) CL(5) DO(6) CE(3)
SanyoCCB ccb(10, 9, 12, 11);
byte pll_in1[3];
byte pll_in2[3];
// Initial frequencies
uint16_t FMFrequency = readWord(space [alamat]); // SIMPLEX
//uint16_t FMFrequency1 = readWord(duplex[alamat]); // DUPLEX
uint16_t Fmax ;
uint16_t Fmin ;
uint8_t band = YST93x_BAND_FM;
uint8_t tuned = 0;
void YST93xInit() {
memset(pll_in1, 0, 3);
memset(pll_in2, 0, 3);
}
void YST93xSetMode(uint8_t mode) {
switch (mode) {
case YST93x_BAND_FM:
band = YST93x_BAND_FM;
bitWrite(pll_in1[0], IN10_R0, 0);
bitWrite(pll_in1[0], IN10_R1, 1);
bitWrite(pll_in1[0], IN10_R2, 0);
bitWrite(pll_in1[0], IN10_R3, 1);
bitWrite(pll_in1[0], IN10_XS, 1);
bitWrite(pll_in1[0], IN10_DVS, 1);
break;
}
ccb.write(0x82, pll_in1, 3);
ccb.write(0x92, pll_in2, 3);
}
uint8_t YST93xTune(uint16_t frequency) {
uint16_t fpd = 0;
uint8_t i = 0;
uint8_t r[3];
unsigned long IFCounter = 0;
switch (band) {
case YST93x_BAND_FM:
fpd = (frequency + 1070);
break;
default: return 1;
}
pll_in1[1] = byte(fpd >> 8);
pll_in1[2] = byte(fpd & 0x00ff);
ccb.write(0x82, pll_in1, 3);
while (i < 1) {
ccb.read(0xa2, r, 3);
i = (bitRead(r[0], DO0_UL)) ? 100 : i + 1;
}
if (i == 2) {
IFCounter = (r[0] & 0x0f);
IFCounter = (IFCounter << 16) | (unsigned long)(r[1] << 8) | (r[2]);
Serial.println (IFCounter);
switch (band) {
case YST93x_BAND_FM:
if ((IFCounter > 342400) && ((IFCounter - 342400) < FM_TUNED_WINDOW)) return 1;
if ((IFCounter < 342400) && ((342400 - IFCounter) < FM_TUNED_WINDOW)) return 1;
break;
}
}
return 0;
}
//untuk signal persen
const int numReadings = 4;
int readings[4];
int readIndex = 0;
int total = 0;
int average = 0;
byte s8[8] = {
0b11111,
0b10001,
0b01010,
0b00100,
0b00100,
0b00100,
0b00100,
0b00100 };
byte bar1[8] = {
0b00000,
0b00000,
0b00000,
0b00000,
0b00000,
0b11000,
0b11000,
0b00000 };
byte bar2[8] = {
0b00000,
0b00000,
0b00000,
0b00000,
0b00011,
0b11011,
0b11011,
0b00000 };
byte bar3[8] = {
0b00000,
0b00000,
0b00000,
0b11000,
0b11000,
0b11000,
0b11000,
0b00000 };
byte bar4[8] = {
0b00000,
0b00011,
0b00011,
0b11011,
0b11011,
0b11011,
0b11011,
0b00000 };
void setup() {
lcd.begin(16, 2);
lcd.setCursor(1, 0);
lcd.print("GapTech BrikFM");
delay(2000);
lcd.createChar(8, s8);
lcd.createChar(1, bar1);
lcd.createChar(2, bar2);
lcd.createChar(3, bar3);
lcd.createChar(4, bar4);
pinMode(Sql, OUTPUT);
pinMode(swPtt, OUTPUT);
digitalWrite(swPtt, 0);
//pinMode(rfLOW, OUTPUT);
//pinMode(rfHGH, OUTPUT);
pinMode(encoderPinA, INPUT_PULLUP);
pinMode(encoderPinB, INPUT_PULLUP);
pinMode(encoderSwit, INPUT_PULLUP);
pinMode(PTT, INPUT_PULLUP);
pinMode(ST, INPUT_PULLUP);
pinMode(VSM, INPUT);
ccb.init();
delay(500);
YST93xInit();
YST93xSetMode(YST93x_BAND_FM);
tuned = YST93xTune(FMFrequency);
attachInterrupt(0, updateEncoder, CHANGE);
attachInterrupt(1, updateEncoder, CHANGE);
lcd.clear();
delay(500);
}
// Rotary
void updateEncoder() {
int MSB = digitalRead(encoderPinA);
int LSB = digitalRead(encoderPinB);
int encoded = (MSB << 1) | LSB;
int sum = (lastEncoded << 2) | encoded;
if (sum == 0b1110) {
key = 1;
}
if (sum == 0b1101) {
key = 2;
}
lastEncoded = encoded;
}
void Signal() {
total = total - readings [readIndex];
readings [readIndex] = analogRead(VSM);
total = total + readings [readIndex];
readIndex = readIndex +1;
if (readIndex >= numReadings) {
readIndex = 0; }
average = total / numReadings;
sinyal = map (average, 0, 1023, 0, 60);
int agcpin = (sinyal /agc );
lcd.setCursor(0, 0);
lcd.write((uint8_t)8);
lcd.print (" ");
if (sinyal <= 15) {
lcd.write ((uint8_t)1);
}
else
if (sinyal <= 25) {
lcd.write ((uint8_t)1);
lcd.write ((uint8_t)2);
}
else
if (sinyal <= 35) {
lcd.write ((uint8_t)1);
lcd.write ((uint8_t)2);
lcd.write ((uint8_t)3);
}
else
if (sinyal <= 45) {
lcd.write ((uint8_t)1);
lcd.write ((uint8_t)2);
lcd.write ((uint8_t)3);
}
else
if (sinyal > 50) {
lcd.write ((uint8_t)1);
lcd.write ((uint8_t)2);
lcd.write ((uint8_t)3);
lcd.write ((uint8_t)4);
}
lcd.print (" ");
lcd.print(agcpin);
lcd.print (" ^ ");
if (sinyal >= 10) {
digitalWrite(Sql, 1);}
else
if (sinyal <= 10) {
digitalWrite(Sql, 0);}
}
void FM() {
Signal();
lcd.setCursor(7, 1);
lcd.print("FM");
lcd.setCursor(0, 1);
lcd.print("C");
lcd.print(alamat);
lcd.print(" ");
// Simplex
bandM=0;
lcd.setCursor((FMFrequency < 1000) ? 4 : 10, 1);
lcd.print((float)FMFrequency / 100, 2);
lcd.print(" MHz ");
tuned = YST93xTune(FMFrequency);
if (key != 0) {
switch (key) {
case 1: delta = +Step; break;
case 2: delta = -Step; break;
case 3: delta = 0; break;
}
if ((key <= 1) + (key >= 2)) {
FMFrequency += delta;
if (FMFrequency > Fmax) {
FMFrequency = Fmin;
}
if (FMFrequency < Fmin) {
FMFrequency = Fmax;
}
}
}
if (digitalRead(encoderSwit) == 0) {
while (digitalRead(encoderSwit) == 0) {}
menu1 = 1; delay(50);
}
if (digitalRead(ST) == 0) {
lcd.setCursor(13, 0);
lcd.print("St"); //memunculkan teks saat stereo atau Tuning
}
else if (digitalRead(ST) == 1) {
lcd.setCursor(13, 0);
lcd.print("--"); //memunculkan teks saat mono
}
key = 0;
}
void step10() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("STEP 10Khz");
lcd.setCursor(0, 1);
lcd.print(" ");
switch (key) {
case 1: menu1 ++; break;
case 2: menu1 = 4; break;
case 3:
Step = 1;
writeWord (44, Step);
delay(1000);
lcd.clear();
delay(100);
menu1 = 0;
break;
}
if (digitalRead(PTT) == 0) {
lcd.clear();
delay(50);
menu1 = 0;
}
key = 0;
}
void step100() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("STEP 100KHz");
lcd.setCursor(0, 1);
lcd.print(" ");
switch (key) {
case 1: menu1 ++; break;
case 2: menu1 --;break;
case 3:
Step = 10;
writeWord (44, Step);
delay(1000);
lcd.clear();
delay(100);
menu1 = 0;
break;
}
if (digitalRead(PTT) == 0) {
lcd.clear();
delay(50);
menu1 = 0;
}
key = 0;
}
void memory1() {
lcd.clear();
alamat = addressN;
lcd.setCursor(0, 1);
lcd.print("C");
lcd.print(addressN);
lcd.print(" ");
lcd.print((float)readWord(space[addressN]) / 100, 2);
lcd.print(" MHz ");
tuned = YST93xTune(readWord(space[addressN]));
switch (key) {
case 1: addressN++; break;
case 2: addressN--; break;
case 3:
lcd.clear();
writeWord(40, alamat);
FMFrequency = readWord(space[alamat]);
delay(50);
menu1 = 0;
break;
}
if (addressN > urutan) {
addressN = 0;
}
else if (addressN < 0) {
addressN = urutan;
}
if (digitalRead(PTT) == 0) {
lcd.clear();
delay(50);
menu1 = 0;
}
key = 0;
}
void memory2() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("<SAVE TO CH>");
lcd.setCursor(0, 1);
lcd.print("CH");
lcd.print(addressN);
lcd.print(" ");
lcd.print((float)FMFrequency / 100, 2);
lcd.print(" MHz ");
if (key != 0) {
switch (key) {
case 1: addressN++; break;
case 2: addressN--; break;
case 3:
alamat = FMFrequency;
writeWord(40, alamat);
writeWord((space[alamat]), FMFrequency);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" Tersimpan..! ");
delay(1000);
lcd.clear();
delay(100);
menu1 = 0;
break;
}
if (addressN > urutan ) {
addressN = 0;
}
else if (addressN < 0) {
addressN = urutan;
}
}
if (digitalRead(PTT) == 0) {
lcd.clear();
delay(50);
menu1 = 0;
}
key = 0;
}
void loop() {
if (bandM == 0) {
Fmax = 10800;
Fmin = 7600;
}
/*else if (bandM == 1) {
Fmax = 10800;
Fmin = 8700;
}*/
if (digitalRead(encoderSwit) == 0) {
while (digitalRead(encoderSwit) == 0) {}
key = 3;
}
switch (menu1) {
case 0: FM(); break;
case 1: step10(); break;
case 2: step100(); break;
case 3: memory2(); break;
case 4: memory1(); break;
}
if (menu1 < 0) {
menu1 = 5;
}
if (menu1 > 5) {
menu1 = 0;
}
key = 0;
}