ICOM IC-705 için “SAT BOX” Uydu Modu

ICOM IC-705’ten popüler QRP alıcı-vericisini uydu uyumlu hale getirebilmek için başka bir devre tasarladım ve buna karşılık gelen yazılımı geliştirdim.

Artık CI-V’yi Bluetooth üzerinden “QO-100 uydu işletimi” için kullanmak mümkün. Önceki versiyonlarda olduğu gibi, TX VFO, ayar düğmesini çevirerek otomatik olarak RX VFO’yu takip ediyor. Böylece iki VFO senkronize edilmiş olur.

İlgili RX ve TX osilatör frekanslarını girerek, hangi yukarı veya aşağı dönüştürücüyü kullanmak istediğinizi özgürce seçebilirsiniz. Örneğin 10m, 6m, 2m, 70cm, 23cm bantlarındaki dönüştürücüleri kullanabilirsiniz. 

RX ve TX için sadece 2 farklı bandı kullanmanız yeterli.

İşte 2m bandından yukarı dönüştürücü (osilatör 2256MHz) ve 70cm bandına aşağı dönüştürücü (osilatör 10054MHz) için ICOM IC-705’li bir örnek.

SAT kutusu Bluetooth aracılığıyla vericiye bağlanır. SAT kutusuna 12V güç verildiğinde Arduino, dahili Bluetooth modülü aracılığıyla alıcı-vericiye CI-V komutları gönderir. Bu otomatik olarak uygun bantlara ayarlanır, USB çalışma modu ayarlanır, split modu etkinleştirilir, RF gücü önceden ayarlanmış bir değere ayarlanır. Frekans orta QO-100 işaretine ayarlanmıştır. Frekanslar Arduino tarafından CI-V arayüzü üzerinden okunur. Dönüştürülen downlink ve uplink frekansı görüntülenir.

RX-VFO üzerindeki alım frekansı değiştirildiğinde, Arduino CI-V üzerinden frekansı alır, dönüştürür ve hesaplanan downlink frekansını ekranda görüntüler. Buradan iletim frekansı hesaplanır ve TX-VFO’ya yazılır. Ortaya çıkan uplink frekansı ekranda gösterilir.

 

Frekans gösterimi:

Frekans gösteriminde, hesaplanan aşağı bağlantı frekansı üst satırda, hesaplanan yukarı bağlantı frekansı ise alt satırda gösterilir. RX veya TX tanımı önündeki sembol, mevcut iletim veya alım durumunu gösterir. Ekranın sağ alt köşesindeki titreşen sembol aktif bir CI-V bağlantısını gösterir.

Kurulum menüsü:

Cihazınızı açarken menü tuşuna basılı tutarak kurulum menüsüne girebilirsiniz.

Önemli !

Transceiver ayarlarında CI-V BAUDRATE 9600 olarak ayarlanmalı ve CI-V TRANSCEIVE kapalı olarak ayarlanmalıdır.

CI-V aygıt adresinin ayarlanması:

Öncelikle doğru CI-V adresinin ayarlanması gerekir.

Cihaz adresi yukarı veya aşağı tuşuna basılarak ayarlanabilir. SAT kutusunda ayarlanan adres, alıcı-vericideki adresle aynı olmalıdır, aksi takdirde SAT kutusu ile IC-705 arasında hiçbir iletişim kurulamaz.

(fabrika varsayılan adresi A4 )

Menü tuşuna tekrar basılarak çıkış gücü ayarlanabilir.

Çıkış gücünün ayarlanması:

Çıkış gücü yukarı veya aşağı tuşuna basılarak ayarlanabilir.

Bu ayarlanan güç, her Bluetooth eşleştirmesi sırasında alıcı-vericiye gönderilir.

Tekrar menü tuşuna basarak adres ve güç ayarlarının yapıldığı hafıza alanına girilir.

Daha önce ayarlanan cihaz adresi ve güç yukarı tuşuna basılarak EEPROM’a kaydedilebilir (güç kaynağı kesildikten sonra bile bu kalır) veya aşağı veya menü tuşuna basılarak kaydetmeden frekans göstergesine geçilebilir.

Menü kontrolü:

Menü tuşuna basarak TX osilatör frekansının ayar aralığına girilir.

Osilatör frekansı, yukarı veya aşağı düğmesine basılarak seçilen artışlarla (10 Hz – 100 MHz) ayarlanabilir.

Bu, SAT-BOX’ta görüntülenen TX frekansını kalibre eder.

Tehlike:

Değişiklik yaptıktan sonra mutlaka en sonda kaydetmeniz gerekmektedir çünkü ana ekranda sadece kaydedilen osilatör frekansı gösterilmektedir.

Menü tuşuna tekrar basarak RX osilatör frekansının ayar aralığına girilir.

Osilatör frekansı, yukarı veya aşağı düğmesine basılarak seçilen artışlarla (10 Hz – 100 MHz) ayarlanabilir.

Bu, SAT-BOX’ta görüntülenen RX frekansını kalibre eder.

Tehlike:

Değişiklik yaptıktan sonra mutlaka en sonda kaydetmeniz gerekmektedir çünkü ana ekranda sadece kaydedilen osilatör frekansı gösterilmektedir.

2m, 70cm, 23cm ama aynı zamanda 6m veya 10m’de dönüştürücüleri kullanmak için herhangi bir osilatör frekansı girilebilir.

(bkz. Excel dosyası “Frekans hesaplaması”)

Menü düğmesine tekrar basarak bölünmüş ofsetin ayar alanına girersiniz

Bölünmüş modda yayın yapan istasyonların da kullanılabilmesini sağlamak için, bölünmüş ofset ayarlama menüsü mevcuttur. Burada sadece TX frekansı değiştiriliyor.

Örnek:  Alınan istasyon “5 yukarı” gösteriyorsa, Split Offset ayarı 5000 Hz olarak girilebilir. TX sinyali daha sonra 5 KHz daha yüksek olarak iletilir.

Veya alınan istasyon “10 down” gösteriyorsa, Split Offset ayarı -10000 Hz olarak girilebilir. TX sinyali daha sonra 10 KHz daha düşük iletilir.

Bir duyuru:

Yeniden başlatma veya sıfırlama sonrasında, bölme ofseti tekrar 0’a ayarlanır.

Not: Bölünmüş ofset EEPROM’da saklanmaz!

Tekrar menü tuşuna basarak adım boyutu ayar alanına girilir.

Varsayılan adım boyutu 100Hz’dir.

10 Hz ile 100 MHz aralığında yukarı tuşuna basılarak adım büyüklüğü 10 katına kadar artırılabilir veya aşağı tuşuna basılarak adım büyüklüğü 10 katına kadar azaltılabilir.

Burada ayarlanan adım boyutu tüm menüler için geçerlidir.

Tekrar menü tuşuna basarak osilatör frekanslarının hafıza alanına girilir.

Daha önce ayarlanmış olan RX ve TX osilatör frekansları yukarı tuşuna basılarak EEPROM’a kaydedilebilir (güç kaynağı kesildikten sonra bile bunlar kalır) veya menü veya aşağı tuşuna basılarak kaydetmeden frekans göstergesine dönülebilir.

Not: Bölünmüş ofset EEPROM’da saklanmaz!

Depolanan RX ve TX osilatör frekansları, yeniden başlatma veya sıfırlama sonrasında bile EEPROM’dan okunur ve frekans göstergesine dahil edilir. Frekans göstergesi artık kalibre edildi.

Frekans göstergesinde yukarı ve aşağı tuşlarına aynı anda uzun süre basıldığında sıfırlama tetiklenir. SAT-BOX kontrol cihazı yeniden başlatılır ve başlatma dizisi görüntülendikten sonra frekans orta işarete geri ayarlanır. Alıcı-verici üzerinde önceden ayarlanmış güç ayarı yapılır. Ayarlanmış olabilecek herhangi bir bölünme ofseti de 0’a sıfırlanacak ve adım boyutu 100 Hz’e sıfırlanacaktır.

Ayrıca menü gezintisi için ilgili kullanım talimatlarına da bakın ( yazılım indirme zip dosyasında yer almaktadır )

Talep üzerine boş panolar da eklenebilir.

Yeniden yapılanmada başarılar dilerim.

Elektronik veya mikrodenetleyici programlama ile daha az uğraşmak isteyen YL’ler veya OM’ler için:

Talep üzerine, montajı tamamlanmış, programlanmış modüller de mevcuttur.

/* Erstellt: 2024-10-26
 * Version V1.1
 * Autor:  Roland Kaiser, OE2ROL
 * Geschrieben für Arduino Nano ATmega 328P(Old Bootloader)
 * Der Autor übernimmt keine Haftung etwaiger Folgeschäden an Transceivern oder dgl.
    
 * Diese Software ist für den eigenen privaten Gebrauch frei verfügbar, jedoch nicht für kommerzielle Zwecke ohne Genehmigung des Autors.
 * Veränderungen und Verbesserungen der Software bitte wieder an den Autor Roland Kaiser OE2ROL (roland.kaiser@sbg.at) senden.
 * Die Software wurde am ICOM IC-705 getestet.
 
 * Funktionsweise:
 
   o  Der Transceiver wird bei einer Bluetoothverbindung automatisch in den entsptechenden "SAT Mode" gebracht (beide VFO´s in die vorgegebene QRG, Betriebsart USB, Splitmode)
   o  Der RX VFO wird gelesen, davon wird ein vorgegebener Versatz subtrahiert und verzögert automatisch in den TX VFO geschrieben.
   o  Dies passiert vollautomatisch nur durch verändern des RX VFO´s.
   o  Die für QO-100 umgerechnete RX und TX Frequenz wird auf einem LCD Display angezeigt. 
   o  Menüsteuerung in 5 Ebenen:
       o Setzen der RX-Oszillatorfrequenz mit einstellbarer Schrittweite zum Anpassen der Oszillatorfrequenz des Upconverters
       o Setzen der TX-Oszillatorfrequenz mit einstellbarer Schrittweite zum Anpassen der Oszillatorfrequenz des Downconverters
       o Setzen eines Split-Offsets mit eingestellbarer Schrittweite für Stationen die im Split-Betrieb arbeiten (hier wird nur die Sendefrequenz verändert)
       o Setzen der Schrittweite für alle Einstellungen
       o Speichern der RX/TX Oszillatorfrequenzen im internen EEPROM.
   o  Nach dem Speichern der Oszillatorfrequenzen wird nach einem Neustart der SAT BOX die Frequenz auf die mittlere QO-100 Bake gestellt.
   o  Die RX und TX Oszillatorfrequenzen bleiben auch ohne Stromversorgung gespeichert, der Split Offset wird wieder auf 0 gesetzt.
   o  Ein Softwarereset kann durch gleichzeitiges betätigen der Up- und Down-Taste ausgelöst werden. (nur in der Frequenzanzeige)
   o  Setup Menüsteuerung in 3 Ebenen:
       o  Die CI-V Adresse kann im Setupmenü gesetzt werden (halten der Menütaste beim Start) z.B. "A4" bei ICOM IC-705 und kann im EEPROM gespeichert werden.
       o  Die Ausgangsleistung kann im Setupmenü gesetzt werden (halten der Menütaste beim Start) z.B. "50%" und kann im EEPROM gespeichert werden.
       o Speichern der CI-V Adresse und der Ausgangsleistung in % im internen EEPROM.
   o  Statusanzeige RX-TX im Display mittels Symbol vor der RX bzw. TX Beschriftung.
   o  Statusanzeige einer aktiven CI-V Verbindung zum Transceiver im Display mittels blinkenden Symbol rechts unten.
 
   Änderungsübersicht:
   V1.0 initiale Version
   V1.1 Leistungseinstellung im Setup Menü hinzugefügt
      
   Anschlussbelegung der Ports:
   
   CAT port GND -> Arduino GND
   CAT port TX,RX  -> Arduino pin 11,12
   
   Tastenport up      -> Arduino Pin A3
   Tastenport down    -> Arduino Pin A4
   Tastenport Menü    -> Arduino Pin A5
   Die Tasten werden gegen Masse angeschlossen.

   BTconnPin          -> Arduino Pin A0
   
   Display:     Arduino:
   4(RS)    ->  7
   6(E)     ->  10
   11(D4)   ->  5
   12(D5)   ->  4
   13(D6)   ->  6
   14(D7)   ->  2
 */

#include <LiquidCrystal.h>
#include <SoftwareSerial.h>
#include <EEPROM.h>

uint32_t freq;                        // Frequenz
uint32_t RXfreq;                      // umgerechnete Empfangsfrequenz
uint32_t TXfreq;                      // umgerechnete Sendefrequenz
uint32_t TXosz;                       // TX Oszillatorfrequenz
uint32_t RXosz;                       // RX Oszillatorfrequenz
uint32_t shift;                       // RX-TX Frequenzversatz
byte civadr = 0;                      // CI-V Adresse
uint32_t VFOAfreq = 0;                // RX Frequenz am Transceiver
uint32_t VFOBfreq = 0;                // TX Frequenz am Transceiver
const uint32_t decMulti[]    = {1000000000, 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10, 1}; // Multiplikatorarray für Frequenzberechnung
byte lcdNumCols = 20;                 // LCD Anzahl der Stellen
uint32_t freqmem;                     // Frequenzzwischenspeicher
long RIT = 0;                         // RIT
long Splitoffset =0;                  // Split Offset
unsigned long previousMillis1 = 0;    // Timer1 auf 0 setzen
unsigned long previousMillis2 = 0;    // Timer2 auf 0 setzen
const long interval = 3500;           // Verzögerungszeit [ms] nachziehen des VFOB
const int BTconnPin = A0;             // Pin für BT Verbindungserkennung
const int menuPin = A5;               // Pin für Menue Taste
const int downpin = A4;               // Pin für Up Taste
const int uppin = A3;                 // Pin für Down Taste
int menuPushCounter = 0;              // Menütastenzähler
int menuState = 0;                    // Menüstatus
int BTstate;                          // BT Status
int lastmenuState = 0;                // letzter Menü Status
boolean menubool = false;             // Menü initial deaktivieren
int up;                               // up Taste
int down;                             // Taste down
int menucounter = 0;                  // Menü Zähler
int initflag = 0;                     // Initflag             
uint32_t sw = 10;                     // Schrittweite zum Einstellen der Oszillatorfrequenzen im Menü Hz/10
byte Z_E;                             // BCD Code   10   Hz,   1 Hz
byte K_H;                             // BCD Code   1   KHz, 100 Hz
byte HK_ZK;                           // BCD Code   100 KHz,  10 KHz
byte ZM_M;                            // BCD Code   10  MHz,   1 MHz
byte G_HM;                            // BCD Code   1   GHz, 100 MHz
int txPower;                          // TX Power in %

LiquidCrystal lcd(7, 10, 5, 4, 6, 2); // LCD Anschlussbelegung
SoftwareSerial CAT(11, 12);           // RX, TX Pin CAT Schnittstelle

// ******************************************SETUP*************************************************************
void setup(){  
CAT.begin(9600);                      // CAT Schnittstelle initialisieren
Serial.begin(9600);                   // Serial Monitor Init
lcd.begin(2, lcdNumCols);             // LCD init
lcd.clear();                          // LCD löschen
delay(100);                           // Verzögerung
pinMode(menuPin, INPUT);              // Init für die Tasten Pins
digitalWrite(menuPin, HIGH);          // Init für die Tasten Pins
pinMode(downpin, INPUT);              // Init für die Tasten Pins
digitalWrite(downpin, HIGH);          // Init für die Tasten Pins
pinMode(uppin, INPUT);                // Init für die Tasten Pins
digitalWrite(uppin, HIGH);            // Init für die Tasten Pins
pinMode(BTconnPin, INPUT);            // Init für BT Pin

menuState = digitalRead(menuPin);     // Auslesen der Menütaste beim Start
if (menuState == LOW){setupmenu();}   // wenn während dem Start die Menü Taste betätigt wird startet das Setupmenü
civadr = EEPROM.get(20, civadr);      // CI-V Adresse aus dem eeprom lesen 

// *****************************************Transceiver Settings setzen***************************************
select_VFOB();                        // VFOB auswählen
delay(20);                            // Verzögerung 20ms  
select_Mode_USB();                    // Umschalten auf Mode USB
delay(20);                            // Verzögerung 20ms  
RXosz = EEPROM.get(10, RXosz);        // RX Oszillatorfrequenz [Hz/10] aus dem EEPROM lesen
select_VFOA();                        // VFOA auswählen
delay(20);                            // Verzögerung 20ms  
select_Mode_USB();                    // Umschalten auf Mode USB
delay(20);                            // Verzögerung 20ms  
select_Split();                       // Umschalten auf Split Mode                                    
delay(20);                            // Verzögerung 20ms
txPower = EEPROM.get(30, txPower);    // TX Power aus dem EEPROM lesen
delay(20);                            // Verzögerung 20ms
set_TXPower(txPower);                 // TX Power setzen
delay(20);                            // Verzögerung 20ms                  
freq = (1048975000-RXosz)*10;         // auf die mittlere QO-100 Bakenfrequenz stellen
write_freq();                         // Frequenz in den Transceiver schreiben

// **************************************Initmeldung***********************************************************
lcd.clear();                          // LCD löschen
lcd.setCursor(0, 0);                  // 1. Zeichen, 1. Zeile
lcd.print("** QO-100 SAT BOX **");    // schreiben
lcd.setCursor(0, 1);                  // 1. Zeichen, 2. Zeile
lcd.print("  **** OE2ROL ****  ");    // schreiben
lcd.setCursor(18, 3);                 // 1. Zeichen, 4. Zeile
lcd.print("ICOM IC-705 V1.1");        // schreiben
delay(2000);                          // Verzögerung
lcd.clear();                          // LCD löschen

  EEPROM.get(0, TXosz);
  if(TXosz == -1){
    // Wird nur bei der  1. Initialisierung eines neuen Arduinos verwendet
    TXosz=2256000000;                               // TX Oszillatorfrequenz [Hz]    (z.B. 2256MHz)
    RXosz=1005400000;                               // RX Oszillatorfrequenz [Hz/10] (z.B. 10,054GHz)
    civadr=0xA4;                                    // CI-V Adresse [HEX] (z.B. A4 Standardadresse ICOM IC-705)
    txPower=1;                                      // TX Power 1% 
    EEPROM.put(0, TXosz);                           // Wert TXosz ins EEPROM schreiben (Adresse 0) 
    delay(200);                                     // Verzögerung
    EEPROM.put(10, RXosz);                          // Wert RXosz ins EEPROM schreiben (Adresse 10)
    delay(200);                                     // Verzögerung
    EEPROM.put(20, civadr);                         // Wert ins eeprom schreiben (Adresse 20)
    delay(200);                                     // Verzögerung
    EEPROM.put(30, txPower);                        // Wert ins eeprom schreiben (Adresse 30)
    delay(200);                                     // Verzögerung
  }
  
}

// *************************************Statusanzeige der CI-V Kommunikation***********************************************************
void puls(){
  unsigned long currentMillis = millis();                    // Wert für aktuellen Timer setzen 
    if (currentMillis - previousMillis1 >= 250)              // wenn Differenz des aktuellen Timers zu Startwert des Timers > 250ms ist, dann:
      {
        lcd.setCursor(37, 3);                                // Cursor setzen
        lcd.print("*");                                      // Zeichen ausgeben 
          if (currentMillis - previousMillis1 >= 500){       // wenn Differenz des aktuellen Timers zu Startwert des Timers > 500ms ist, dann:
            lcd.setCursor(37, 3);                            // Cursor setzen
            lcd.print(" ");                                  // Zeichen ausgeben
            previousMillis1 = currentMillis;                 // Timerstartwert auf Wert des aktuellen Timers setzen
          }
      }
}

// ********************************************Aufbau einer Bluetoothverbindung**********************************************************
void Bluetoothstate(){
  BTstate = digitalRead(BTconnPin);     // Auslesen des BT Pins
    if (BTstate == LOW){                // wenn BT nicht verbunden ist
       asm volatile ("  jmp 0");        // Software Reset
    }
    else{
      if (initflag == 0){               // wenn BT verbunden ist
        setup();                        // erneute Ausführung von Setup
        initflag = 1;                   // Flag auf 1  setzen, damit Setup nach der ersten BT Verbindung nur einmal ausgeführt wird
      }
    }
}   

// ********************************************LCD Beschriftung setzen******************************************************************
void LCDBeschriftung() {
  lcd.setCursor(1, 0);                  // 2. Zeichen, 1. Zeile
  lcd.print("RX");                      // schreiben
  lcd.setCursor(17, 0);                 // 18. Zeichen, 1. Zeile
  lcd.print("MHz");                     // schreiben
  lcd.setCursor(1, 1);                  // 2. Zeichen, 2. Zeile
  lcd.print("TX");                      // schreiben
  lcd.setCursor(17, 1);                 // 18. Zeichen, 2. Zeile
  lcd.print("MHz");                     // schreiben
  }

//*************************************************************RX_TX Beschriftung*******************************************************
void RXTXBeschriftung() {

  if (VFOAfreq != VFOBfreq) {           // wenn VFOAfreq ungleich VFOBfreq ist (RX) dann
    lcd.setCursor(0, 0);                // 1. Zeichen, 1. Zeile
    lcd.print("*");                     // schreiben
  }
  else{                                 // sonst
    lcd.setCursor(0, 0);                // 1. Zeichen, 1. Zeile
    lcd.print(" ");                     // schreiben
  }
  if (VFOAfreq == VFOBfreq) {           // wenn VFOAfreq gleich VFOBfreq ist (TX) dann
    lcd.setCursor(0, 1);                // 1. Zeichen, 2. Zeile
    lcd.print("*");                     // schreiben
  }
  else{                                 // sonst
    lcd.setCursor(0, 1);                // 1. Zeichen, 2. Zeile
    lcd.print(" ");                     // schreiben
  }
}

//***************************************************************TX Power setzen*********************************************************
// "00" => 0x00
// "99" => 0x99
byte str2Hex(String value)
{
  int z = value.substring(0,1).toInt();
  return( z*6 + value.toInt() );
}

// 0 - 100 set_TXPower
void set_TXPower(int txPower) {  //(int percentage=77)

  // "00000" - "0000255"
  String value = "0000" + String(int( ( 255.0/100.0 ) * txPower ));             // Prozentwert in Hexwert umrechnen
  
  // "0001" => "0001"
  // "0000255" => "0255"
  value = value.substring(value.length()-4,value.length());                     // in 4 stelligen Hexwert umwandeln

  // "02" => 0x02                                                               // in 4 stelligen Hexwert in 2x 2 stelligen Hexwert umwandeln
  int byte0 = str2Hex( value.substring(0,2) );                                  // 1. 2 Stellen
  // "55" => 0x55
  int byte1 = str2Hex( value.substring(2,4) );                                  // 2. 2 Stellen
  // 0x00  0x00 =>   0
  // 0x02  0x55 => 255
  uint8_t power[] = {0xFE, 0xFE, civadr, 0x00, 0x14, 0x0A, byte0, byte1, 0xFD}; // CAT Kommando zum setzen der TX Power (7.Byte 0x00 0x00 = Minimum bis 8.Byte 0x02 0x55 = Maximum)
                                                                                // Formel 255/100x(Leistung in %) und auf Ganze runden (z.B.30% = 255/100*30 = 76,5 ~ 77 = 0x00, 0x77)
  for (uint8_t i = 0; i < sizeof(power); i++) {                                 // Zählschleife 0 - Grösse des Schreibarrays
    CAT.write(power[i]);                                                        // CAT Kommando senden
    }
  delay(20);                                                                    // Verzögerung 20 ms  
}

// *********************************************Sende- und Empangsfrequenzen berechnen***************************************************
void calculateFrequency()  {
TXosz = EEPROM.get(0, TXosz);               // TX Oszillatorfrequenz [Hz] aus dem eeprom lesen (Adresse 0)
RXosz = EEPROM.get(10, RXosz);              // RX Oszillatorfrequenz [Hz/10] aus dem eeprom lesen (Adresse 10)
shift=808950000;                            // QO-100 RX-TX Versatz [Hz/10] = TX 10489,750MHz RX 2400,250MHz = RX-TX shift 8089,500MHz
TXfreq=VFOBfreq+TXosz;                      // Berechnung der SAT Sendefrequenz [Hz](Sendefrequenz + TX Oszillatorfrequenz)
RXfreq=(VFOAfreq/10)+RXosz;                 // Berechnung der SAT Empfangsfrequenz [Hz/10](Empfangsfrequenz + RX Oszillatorfrequenz)
}

// *************************************************Mode USB am Transceiver auswählen****************************************************
void select_Mode_USB() {
uint8_t VFOA[] = {0xFE, 0xFE, civadr, 0x00, 0x06, 0x01, 0xFD};          // CAT Kommando zum Umschalten auf USB
for (uint8_t i = 0; i < sizeof(VFOA); i++) {                            // Zählschleife 0 - Grösse des Schreibarrays
  CAT.write(VFOA[i]);                                                   // CAT Kommando senden
  }
delay(20);                                                              // Verzögerung 20 ms     
}

// *************************************************Split Mode am Transceiver auswählen**************************************************
void select_Split() {
uint8_t VFOA[] = {0xFE, 0xFE, civadr, 0x00, 0x0F, 0x01, 0xFD};          // CAT Kommando zum Umschalten auf Split
for (uint8_t i = 0; i < sizeof(VFOA); i++) {                            // Zählschleife 0 - Grösse des Schreibarrays
  CAT.write(VFOA[i]);                                                   // CAT Kommando senden
  }
delay(20);                                                              // Verzögerung 20 ms
}

// *************************************************VFOA am Transceiver auswählen********************************************************
void select_VFOA() {
uint8_t VFOA[] = {0xFE, 0xFE, civadr, 0x00, 0x07, 0x00, 0xFD};          // CAT Kommando zum Umschalten auf VFOA
for (uint8_t i = 0; i < sizeof(VFOA); i++) {                            // Zählschleife 0 - Grösse des Schreibarrays
  CAT.write(VFOA[i]);                                                   // CAT Kommando senden
  }
delay(20);                                                              // Verzögerung 20 ms
}

// ***********************************************VFOB am Transceiver auswählen**********************************************************
void select_VFOB() {
uint8_t VFOB[] = {0xFE, 0xFE, civadr, 0x00, 0x07, 0x01, 0xFD};          // CAT Kommando zum Umschalten auf VFOB
for (uint8_t i = 0; i < sizeof(VFOB); i++) {                            // Zählschleife 0 - Grösse des Schreibarray
  CAT.write(VFOB[i]);                                                   // CAT Kommando senden
  }
delay(20);                                                              // Verzögerung 20 ms
}

// ***********************************************TX Frequenz in VFOB schreiben**********************************************************
void write_TXfreq() {
select_VFOB();                                                          // VFOB Frequenz auswählen
delay(20);                                                              // Verzögerung 20 ms
freq = VFOBfreq;                                                        // Frequenz in VFOB Variable schreiben
write_freq();                                                           // Funktion aufrufen zum Schreiben der Frequenz in den Transceiver  
}

// *************************************************Frequenz in Transceiver schreiben****************************************************
void write_freq() {
                                                        
Z_E =   decToBcd(freq%100);                                                                 // 10 Hz,   1 Hz
K_H =   decToBcd(freq/100%100);                                                             // 1 KHz,   100 Hz
HK_ZK = decToBcd(freq/10000%100);                                                           // 100 KHz, 10 KHz
ZM_M =  decToBcd(freq/1000000%100);                                                         // 10 MHz,  1 MHz
G_HM =  decToBcd(freq/100000000%100);                                                       // 1 GHz,   100 MHz

uint8_t writefreq[] = {0xFE, 0xFE, civadr, 0x00, 0x05, Z_E, K_H, HK_ZK, ZM_M, G_HM, 0xFD};  // CAT Kommando zum schreiben der Frequenz z.B. FE FE civadr 00 05 <00 80 20 44 01> FD = 0144208000 Hz
for (uint8_t i = 0; i < sizeof(writefreq); i++) {                                           // Zählschleife 0 - Grösse des Schreibarray
  CAT.write(writefreq[i]);                                                                  // CAT Kommando senden
  }
delay(20);                                                                                  // Verzögerung 20 ms
}

// ******************************************dezimal in BCD Code umwandeln*****************************************************************
byte decToBcd(byte val)                                                 
{
  return( (val/10*16) + (val%10) );                                     // 2 stellige Dezimalzahl in BCD Code umwandeln
}

// ************************************VFOB nachziehen, nur wenn RX Frequenz am Transceiver geändert wird**********************************
void VFOB_nachziehen1() {                                               // nur wenn VFOAfreq > VFOBfreq ist
int dly = 5;                                                            // Verzögerung für x millisekunden zwischen den Kommandos
VFOBfreq=(VFOAfreq/10+RXosz-shift)*10-TXosz-RIT+Splitoffset;            // VFO Freq. zum Senden berechnen [Hz/10](Empfangsfrequenz+RX Oszillatorfrequenz-shift-TX Oszillatorfrequenz) um -RIT und +Splitoffset korrigieren
unsigned long currentMillis = millis();                                 // Wert für aktuellen Timer setzen 
if (currentMillis - previousMillis2 >= interval)                        // wenn Differenz des aktuellen Timers zu Startwert des Timers > Verzögerungszeit ist, dann:
  {
   previousMillis2 = currentMillis;                                     // Timerstartwert auf Wert des aktuellen Timers setzen  
    if (TXfreq > 2399000000) {                                          // Zur Unterdrückung einer falschen Frequenzübergabe
        if (freqmem!=VFOBfreq)                                          // Nur wenn der Zwischenspeicher nicht der VFOA-Frequenz entspricht, dann:
          {
           write_TXfreq();                                              // TX Frequenz in den VFOB schreiben
           delay(dly);                                                  // Verzögerung
           freqmem=VFOBfreq;                                            // TX Frequenz in den Zwischenspeicher schreiben
           delay(dly);                                                  // Verzögerung
          } 
      }
  }
}

// *************************************Berechnete TX Frequenz ins Display schreiben*******************************************************
void print_TXfreq1() {                 // nur wenn VFOAfreq > VFOBfreq ist
  if (TXfreq > 2399000000)  {          // Zur Unterdrückung einer falschen Frequenzanzeige bei manueller Wahl des VFOB
    lcd.setCursor(5, 1);
    lcd.print(TXfreq/1000000000%10);   // Tx 1G Stelle ausgeben
    lcd.setCursor(6, 1);
    lcd.print(TXfreq/100000000%10);    // Tx 100M  Stelle ausgeben
    lcd.setCursor(7, 1);
    lcd.print(TXfreq/10000000%10);     // Tx 10M Stelle ausgeben
    lcd.setCursor(8, 1);
    lcd.print(TXfreq/1000000%10);      // Tx 1M Stelle ausgeben
    lcd.setCursor(9, 1);
    lcd.print(",");                    // , ausgeben
    lcd.setCursor(10, 1);
    lcd.print(TXfreq/100000%10);       // Tx 100k Stelle ausgeben
    lcd.setCursor(11, 1);
    lcd.print(TXfreq/10000%10);        // Tx 10k Stelle ausgeben
    lcd.setCursor(12, 1);
    lcd.print(TXfreq/1000%10);         // Tx 1k Stelle ausgeben
    lcd.setCursor(13, 1);
    lcd.print(TXfreq/100%10);          // Tx 100Hz Stelle ausgeben
    lcd.setCursor(14, 1);
    lcd.print(TXfreq/10%10);           // Tx 10Hz Stelle ausgeben
    lcd.setCursor(15, 1);
    lcd.print(TXfreq%10);              // Tx 1Hz Stelle ausgeben
  }
}

// *************************************Berechnete RX Frequenz ins Display schreiben******************************************************
void print_RXfreq1() {                 // nur wenn VFOAfreq > VFOBfreq ist
  if (RXfreq > 1048800000)  {          // Zur Unterdrückung einer falschen Frequenzanzeige beim Senden
    lcd.setCursor(2, 2);
    lcd.print(RXfreq/1000000000%10);   // Rx 10G Stelle ausgeben
    lcd.setCursor(3, 2);
    lcd.print(RXfreq/100000000%10);    // Rx 1G Stelle ausgeben
    lcd.setCursor(4, 2);
    lcd.print(RXfreq/10000000%10);     // Rx 100M Stelle ausgeben
    lcd.setCursor(5, 2);
    lcd.print(RXfreq/1000000%10);      // Rx 10M Stelle ausgeben
    lcd.setCursor(6, 2);
    lcd.print(RXfreq/100000%10);       // Rx 1M Stelle ausgeben
    lcd.setCursor(7, 2);
    lcd.print(",");                    // , ausgeben
    lcd.setCursor(8, 2);
    lcd.print(RXfreq/10000%10);        // Rx 100k Stelle ausgeben
    lcd.setCursor(9, 2);
    lcd.print(RXfreq/1000%10);         // Rx 10k Stelle ausgeben
    lcd.setCursor(10, 2);
    lcd.print(RXfreq/100%10);          // Rx 1k Stelle ausgeben
    lcd.setCursor(11, 2);
    lcd.print(RXfreq/10%10);           // Rx 100Hz Stelle ausgeben
    lcd.setCursor(12, 2);
    lcd.print(RXfreq%10);              // Rx 10Hz Stelle ausgeben
    lcd.setCursor(13, 2);
    lcd.print(RXfreq%1);               // Rx 1Hz Stelle ausgeben 
  }
}

// ************************************VFOB nachziehen, nur wenn RX Frequenz am Transceiver geändert wird**********************************
void VFOB_nachziehen2() {                                               // nur wenn VFOAfreq < VFOBfreq ist
int dly = 5;                                                            // Verzögerung für x millisekunden zwischen den Kommandos
VFOBfreq=(VFOAfreq/10+RXosz-shift)*10-TXosz-RIT+Splitoffset;            // VFO Freq. zum Senden berechnen [Hz/10](Empfangsfrequenz+RX Oszillatorfrequenz-shift-TX Oszillatorfrequenz) um -RIT und +Splitoffset korrigieren
unsigned long currentMillis = millis();                                 // Wert für aktuellen Timer setzen 
if (currentMillis - previousMillis2 >= interval)                        // wenn Differenz des aktuellen Timers zu Startwert des Timers > Verzögerungszeit ist, dann:
  {
   previousMillis2 = currentMillis;                                     // Timerstartwert auf Wert des aktuellen Timers setzen  
    if (TXfreq < 2401000000) {                                          // Zur Unterdrückung einer falschen Frequenzübergabe
        if (freqmem!=VFOBfreq)                                          // Nur wenn der Zwischenspeicher nicht der VFOA-Frequenz entspricht, dann:
          {
           write_TXfreq();                                              // TX Frequenz in den VFOB schreiben
           delay(dly);                                                  // Verzögerung
           freqmem=VFOBfreq;                                            // TX Frequenz in den Zwischenspeicher schreiben
           delay(dly);                                                  // Verzögerung
          } 
      }
  }
}

// *************************************Berechnete TX Frequenz ins Display schreiben*******************************************************
void print_TXfreq2() {                 // nur wenn VFOAfreq < VFOBfreq ist
  if (TXfreq < 2401000000)  {          // Zur Unterdrückung einer falschen Frequenzanzeige bei manueller Wahl des VFOB
    lcd.setCursor(5, 1);
    lcd.print(TXfreq/1000000000%10);   // Tx 1G Stelle ausgeben
    lcd.setCursor(6, 1);
    lcd.print(TXfreq/100000000%10);    // Tx 100M  Stelle ausgeben
    lcd.setCursor(7, 1);
    lcd.print(TXfreq/10000000%10);     // Tx 10M Stelle ausgeben
    lcd.setCursor(8, 1);
    lcd.print(TXfreq/1000000%10);      // Tx 1M Stelle ausgeben
    lcd.setCursor(9, 1);
    lcd.print(",");                    // , ausgeben
    lcd.setCursor(10, 1);
    lcd.print(TXfreq/100000%10);       // Tx 100k Stelle ausgeben
    lcd.setCursor(11, 1);
    lcd.print(TXfreq/10000%10);        // Tx 10k Stelle ausgeben
    lcd.setCursor(12, 1);
    lcd.print(TXfreq/1000%10);         // Tx 1k Stelle ausgeben
    lcd.setCursor(13, 1);
    lcd.print(TXfreq/100%10);          // Tx 100Hz Stelle ausgeben
    lcd.setCursor(14, 1);
    lcd.print(TXfreq/10%10);           // Tx 10Hz Stelle ausgeben
    lcd.setCursor(15, 1);
    lcd.print(TXfreq%10);              // Tx 1Hz Stelle ausgeben
  }
}

// *************************************Berechnete RX Frequenz ins Display schreiben******************************************************
void print_RXfreq2() {                 // nur wenn VFOAfreq < VFOBfreq ist
  if (RXfreq < 1049100000)  {          // Zur Unterdrückung einer falschen Frequenzanzeige beim Senden
    lcd.setCursor(2, 2);
    lcd.print(RXfreq/1000000000%10);   // Rx 10G Stelle ausgeben
    lcd.setCursor(3, 2);
    lcd.print(RXfreq/100000000%10);    // Rx 1G Stelle ausgeben
    lcd.setCursor(4, 2);
    lcd.print(RXfreq/10000000%10);     // Rx 100M Stelle ausgeben
    lcd.setCursor(5, 2);
    lcd.print(RXfreq/1000000%10);      // Rx 10M Stelle ausgeben
    lcd.setCursor(6, 2);
    lcd.print(RXfreq/100000%10);       // Rx 1M Stelle ausgeben
    lcd.setCursor(7, 2);
    lcd.print(",");                    // , ausgeben
    lcd.setCursor(8, 2);
    lcd.print(RXfreq/10000%10);        // Rx 100k Stelle ausgeben
    lcd.setCursor(9, 2);
    lcd.print(RXfreq/1000%10);         // Rx 10k Stelle ausgeben
    lcd.setCursor(10, 2);
    lcd.print(RXfreq/100%10);          // Rx 1k Stelle ausgeben
    lcd.setCursor(11, 2);
    lcd.print(RXfreq/10%10);           // Rx 100Hz Stelle ausgeben
    lcd.setCursor(12, 2);
    lcd.print(RXfreq%10);              // Rx 10Hz Stelle ausgeben
    lcd.setCursor(13, 2);
    lcd.print(RXfreq%1);               // Rx 1Hz Stelle ausgeben 
  }
}

// ********************************************RX Frequenz aus dem Transceiver lesen (VFOA)***************************************************
void read_RXfreq() {                                                      // Frequenz vom Transceiver auslesen und in Variable (freq) schreiben
select_VFOA();                                                            // VFOA Frequenz auswählen
delay(100);                                                               // Verzögerung 100 ms
uint8_t freq_buffer[12];                                                  // Array zum Einlesen der Main Frequenz
uint8_t req[] = {0xFE, 0xFE, civadr, 0x00, 0x03, 0xFD};                   // CAT Kommando zum auslesen der Frequenz  
for (uint8_t i = 0; i < sizeof(req); i++) {                               // Grösse des Schreibarrays 
  CAT.write(req[i]);                                                      // CAT Kommando schreiben
  }
delay(100);                                                               // Verzögerung 100 ms
  while (!CAT.available());                                               // auf Serial Port warten
    while (CAT.available() > 0) {                                         // wenn Serial Port verfügbar
      puls();                                                             // Statusanzeige der CI-V Kommunikation ausgeben
      for (int j = 0; j < 12; j++) {                                      // Zählschleife 0-12
        delay(10);                                                        // Verzögerung 10 ms
        freq_buffer[j] = CAT.read();                                      // Zeichen vom Serial Port schrittweise in das Array schreiben
            if (freq_buffer[j] == 0xFD){                                  // wenn 0xFD im Buffer steht
              break;                                                      // aus der Schleife aussteigen
              j = 0;                                                      // Arrayindexzähler auf 0 setzen
            } 
        VFOAfreq = 0;                                                     // Variable für RX Frequenz auf 0 setzen
      }
                                                                          // FE FE 00 A2 03 <00 80 70 35 04> FD = 0435708000 Hz
      for (uint8_t k = 0; k < 5; k++) {                                   // Zählschleife 0-5
          VFOAfreq += (freq_buffer[9 - k] >> 4) * decMulti[k * 2];        // Frequenz aus dem Buffer lesen und in Dezimal konvertieren
          VFOAfreq += (freq_buffer[9 - k] & 0x0F) * decMulti[k * 2 + 1];  // Frequenz aus dem Buffer lesen und in Dezimal konvertieren
      }  
    }
} 

// ********************************************************Softwarereset****************************************************************************
void software_reset(){
up = digitalRead(uppin);                                // up Taste abfragen
down = digitalRead(downpin);                            // down Taste abfragen
            if (up == LOW && down == LOW){              // wenn up und down Taste gleichzeitig betätigt
              asm volatile ("  jmp 0");                 // Software Reset
            }
}

// *******************************************************Menüsteuerung****************************************************************************
void menuset(){
menuState = digitalRead(menuPin);                       // Auslesen der Menütaste
  if (menuState != lastmenuState)                       // wenn sich der Menü Status geändert hat
  {
    if (menuState == LOW)                               // wenn Menü Status LOW (Menütaste gedrückt)
    {
      delay(200);                                       // Verzögerung
      menuPushCounter = 5;                              // maximal 4 Menüs verfügbar Menütastenzähler auf 5 setzen
      menubool = true;                                  // menü aktivieren
    }
    if (menuState == HIGH)                              // wenn Menü Status HIGH
    {
      menubool = false;                                 // menü deaktivieren
    }
  }

  if (menubool == true && menuPushCounter == 5)         // wenn Menü aktiviert und Menütastenzähler 5
  {
    menucounter = 0;                                    // Menüzähler auf 0 setzen 
    menu();                                             // Menü starten
  }
lastmenuState = menuState;                              // Menüstatus setzen
}

// *******************************************Menüsteuerung zum Setzen und Speichern der Offsets***************************************************
int menu()
{
  lcd.clear();                                    // LCD löschen
  delay(100);                                     // Verzögerung
  while (menucounter < 5)                         // while Menu enspricht der max Anzahl der Menüs
  {
    menuState = digitalRead(menuPin);             // Menü Taste abfragen
    up = digitalRead(uppin);                      // up Taste abfragen
    down = digitalRead(downpin);                  // down Taste abfragen

    if (menuState != lastmenuState)               // wenn sich der Menü Status geändert hat
    {
      lcd.clear();                                // LCD löschen
      if (menuState == LOW)                       // wenn Menü Status LOW
      {
        delay(200);                               // Verzögerung
        menucounter++;                            // Menüzähler um 1 erhöhen
      }
    }
lastmenuState = menuState;                        // letzten Menüstatus auf Menü Status setzen

    switch (menucounter) {                        // Menüauswahl
      case 0:                                     // Menü 1
        lcd.setCursor(0, 0);                      // 1. Zeichen, 1. Zeile
        lcd.print("TX Oscillator [Hz]");          // schreiben
        lcd.setCursor(0, 1);                      // 1. Zeichen, 2. Zeile
        lcd.print(TXosz);                         // schreiben
            if (up == LOW)                        // wenn up Taste betätigt
            {
              delay(200);                         // Verzögerung
              TXosz=TXosz+(sw*10);                // Wert um Schrittweite *10 erhöhen
              lcd.clear();                        // LCD löschen
            }
            if (down == LOW)                      // wenn down Taste betätigt
            {
              delay(200);                         // Verzögerung
              TXosz=TXosz-(sw*10);                // Wert um Schrittweite *10 vermindern
              lcd.clear();                        // LCD löschen
            }
        break;                                    // aussteigen, dieses Menü beginnt dann von vorne

      case 1:                                     // Menü 2
        lcd.setCursor(0, 0);                      // 1. Zeichen, 1. Zeile
        lcd.print("RX Oscillator[Hz/10]");        // schreiben
        lcd.setCursor(0, 1);                      // 1. Zeichen, 2. Zeile
        lcd.print(RXosz);                         // schreiben
            if (up == LOW)                        // wenn up Taste betätigt
            {
              delay(200);                         // Verzögerung
              RXosz=RXosz+sw;                     // Wert um Schrittweite erhöhen
              lcd.clear();                        // LCD löschen
            }
            if (down == LOW)                      // wenn down Taste betätigt
            {
              delay(200);                         // Verzögerung
              RXosz=RXosz-sw;                     // Wert um Schrittweite vermindern
              lcd.clear();                        // LCD löschen
            }
        break;                                    // aussteigen, dieses Menü beginnt dann von vorne

      case 2:                                     // Menü 3
        lcd.setCursor(0, 0);                      // 1. Zeichen, 1. Zeile
        lcd.print("Split Offset [Hz]");           // schreiben
        lcd.setCursor(0, 1);                      // 1. Zeichen, 2. Zeile
        lcd.print(Splitoffset);                   // schreiben
            if (up == LOW)                        // wenn up Taste betätigt
            {
              delay(200);                         // Verzögerung
              Splitoffset=Splitoffset+(sw*10);    // Wert um Schrittweite*10 erhöhen
              lcd.clear();                        // LCD löschen
            }
            if (down == LOW)                      // wenn down Taste betätigt
            {
              delay(200);                         // Verzögerung
              Splitoffset=Splitoffset-(sw*10);    // Wert um Schrittweite*10 vermindern
              lcd.clear();                        // LCD löschen
            }
        break;                                    // aussteigen, dieses Menü beginnt dann von vorne
        
      case 3:                                     // Menü 4
        lcd.setCursor(0, 0);                      // 1. Zeichen, 1. Zeile
        lcd.print("Step size");                   // schreiben
            if (up == LOW)                        // wenn up Taste betätigt
            {
              delay(200);                         // Verzögerung
              sw=sw*10;                           // Wert mit 10 multiplizieren
              lcd.clear();                        // LCD löschen
            }
            if (down == LOW)                      // wenn down Taste betätigt
            {
              delay(200);                         // Verzögerung
              sw=sw/10;                           // Wert durch 10 dividieren
              lcd.clear();                        // LCD löschen
            }
            if (sw*10 > 100000000) {sw=1;}        // max Begrenzung auf 100M
            if (sw < 1) {sw=1;}                   // min Begrenzung auf 1
            if (sw*10 < 1000){                    // Beschriftung und Umrechnung in Hz
              lcd.setCursor(0, 1);                // 1. Zeichen, 2. Zeile
              lcd.print(sw*10);                   // schreiben   
              lcd.setCursor(5, 1);                // 5. Zeichen, 2. Zeile
              lcd.print("Hz");                    // schreiben
            }
            if (sw*10 > 999 && sw*10 < 1000000){  // Beschriftung und Umrechnung in KHz
              lcd.setCursor(0, 1);                // 1. Zeichen, 2. Zeile
              lcd.print(sw*10/1000);              // schreiben
              lcd.setCursor(5, 1);                // 5. Zeichen, 2. Zeile
              lcd.print("KHz");                   // schreiben
            }
            if (sw*10 > 999999 && sw*10 < 1000000000){ // Beschriftung und Umrechnung in MHz
              lcd.setCursor(0, 1);                // 1. Zeichen, 2. Zeile
              lcd.print(sw*10/1000000);           // schreiben
              lcd.setCursor(5, 1);                // 5. Zeichen, 2. Zeile
              lcd.print("MHz");                   // schreiben
            }
        break;                                    // aussteigen, dieses Menü beginnt dann von vorne
        
      case 4:                                     // Menü 5, hier werden die Werte gespeichert und der arduino beginnt loop neu auszuführen
        lcd.setCursor(0, 0);                      // 1. Zeichen, 1. Zeile
        lcd.print("store Offsets?");              // schreiben
        lcd.setCursor(0, 1);                      // 1. Zeichen, 2. Zeile
        lcd.print("down or menu= No");            // schreiben
        lcd.setCursor(18, 2);                     // 1. Zeichen, 3. Zeile
        lcd.print("up= Yes");                     // schreiben
            if (up == LOW)                        // wenn up Taste betätigt
            {
              delay(200);                         // Verzögerung
              EEPROM.put(0, TXosz);               // Wert ins eeprom schreiben (Adresse 0)
              delay(200);                         // Verzögerung
              EEPROM.put(10, RXosz);              // Wert ins eeprom schreiben (Adresse 10)
              delay(200);                         // Verzögerung
              lcd.setCursor(0, 1);                // 1. Zeichen, 1. Zeile
              delay(200);                         // Verzögerung
              lcd.clear();                        // LCD löschen
              lcd.print("Offsets stored");        // schreiben
              delay(2000);                        // Verzögerung
              lcd.clear();                        // LCD löschen
              delay(200);                         // Verzögerung
              menucounter = 5;                    // Menü Zähler auf 5 setzen
              menuPushCounter = 0;                // Menütastenzähler auf 0 setzen
              break;                              // aussteigen, zurück zu loop
            }
            if (down == LOW)                      // wenn down Taste betätigt
            {
              lcd.clear();                        // LCD löschen
              delay(200);                         // Verzögerung
              menucounter = 5;                    // Menü Zähler auf 5 setzen
              menuPushCounter = 0;                // Menütastenzähler auf 0 setzen
              break;                              // aussteigen, zurück zu loop
            }
    }
  }
}


// ********************** Menüsteuerung im Setup zum Setzen und Speichern der CI-V Adresse und TX Power *********************************
int setupmenu()
{
  civadr = EEPROM.get(20, civadr);                // CI-V Adresse aus dem eeprom lesen
  txPower = EEPROM.get(30, txPower);              // TX Power in % aus dem eeprom lesen
  lcd.clear();                                    // LCD löschen
  delay(100);                                     // Verzögerung
  while (menucounter < 3)                         // while Menu enspricht der max Anzahl der Menüs
  {
    menuState = digitalRead(menuPin);             // Menü Taste abfragen
    up = digitalRead(uppin);                      // up Taste abfragen
    down = digitalRead(downpin);                  // down Taste abfragen

    if (menuState != lastmenuState)               // wenn sich der Menü Status geändert hat
    {
      lcd.clear();                                // LCD löschen
      if (menuState == LOW)                       // wenn Menü Status LOW
      {
        delay(200);                               // Verzögerung
        menucounter++;                            // Menüzähler um 1 erhöhen
      }
    }
lastmenuState = menuState;                        // letzten Menüstatus auf Menü Status setzen

    switch (menucounter) {                        // Menüauswahl
      case 0:                                     // Menü 1
        lcd.setCursor(0, 0);                      // 1. Zeichen, 1. Zeile
        lcd.print("CI-V Address [HEX]");          // schreiben
        lcd.setCursor(0, 1);                      // 1. Zeichen, 2. Zeile
        lcd.print(civadr, HEX);                   // schreiben
            if (up == LOW)                        // wenn up Taste betätigt
            {
              delay(200);                         // Verzögerung
              civadr=civadr+1;                    // Wert um 1 erhöhen
              lcd.clear();                        // LCD löschen
            }
            if (down == LOW)                      // wenn down Taste betätigt
            {
              delay(200);                         // Verzögerung
              civadr=civadr-1;                    // Wert um 1 vermindern
              lcd.clear();                        // LCD löschen
            }
            if (civadr > 255) {civadr=1;}         // max Begrenzung auf 255
            if (civadr < 0) {civadr=255;}         // min Begrenzung auf 0
            
        break;                                    // aussteigen, dieses Menü beginnt dann von vorne

      case 1:                                     // Menü 2
        lcd.setCursor(0, 0);                      // 1. Zeichen, 1. Zeile
        lcd.print("TX Power [0-100 %]");          // schreiben
        lcd.setCursor(0, 1);                      // 1. Zeichen, 2. Zeile
        lcd.print(txPower);                       // schreiben
            if (up == LOW)                        // wenn up Taste betätigt
            {
              delay(200);                         // Verzögerung
              txPower=txPower+1;                  // Wert um 1 erhöhen
              lcd.clear();                        // LCD löschen
            }
            if (down == LOW)                      // wenn down Taste betätigt
            {
              delay(200);                         // Verzögerung
              txPower=txPower-1;                  // Wert um 1 vermindern
              lcd.clear();                        // LCD löschen
            }
            if (txPower > 100) {txPower=1;}       // max Begrenzung auf 100
            if (txPower < 0) {txPower=100;}       // min Begrenzung auf 0
            
        break;                                    // aussteigen, dieses Menü beginnt dann von vorne

      case 2:                                     // Menü 3, hier werden die Werte gespeichert und der arduino beginnt loop neu auszuführen
        lcd.setCursor(0, 0);                      // 1. Zeichen, 1. Zeile
        lcd.print("store Offsets?");              // schreiben
        lcd.setCursor(0, 1);                      // 1. Zeichen, 2. Zeile
        lcd.print("down or menu= No");            // schreiben
        lcd.setCursor(18, 2);                     // 1. Zeichen, 3. Zeile
        lcd.print("up= Yes");                     // schreiben
            if (up == LOW)                        // wenn up Taste betätigt
            {
              delay(200);                         // Verzögerung
              EEPROM.put(20, civadr);             // Wert ins eeprom schreiben (Adresse 20)
              delay(200);                         // Verzögerung
              EEPROM.put(30, txPower);            // Wert ins eeprom schreiben (Adresse 20)
              delay(200);                         // Verzögerung
              lcd.setCursor(0, 1);                // 1. Zeichen, 1. Zeile
              delay(200);                         // Verzögerung
              lcd.clear();                        // LCD löschen
              lcd.print("Offsets stored");        // schreiben
              delay(2000);                        // Verzögerung
              lcd.clear();                        // LCD löschen
              delay(200);                         // Verzögerung
              menucounter = 3;                    // Menü Zähler auf 2 setzen
              menuPushCounter = 0;                // Menütastenzähler auf 0 setzen
              break;                              // aussteigen, zurück zu loop
            }
            if (down == LOW)                      // wenn down Taste betätigt
            {
              lcd.clear();                        // LCD löschen
              delay(200);                         // Verzögerung
              menucounter = 3;                    // Menü Zähler auf 3 setzen
              menuPushCounter = 0;                // Menütastenzähler auf 0 setzen
              break;                              // aussteigen, zurück zu loop
            }
    }
  }
}


//******************************************************************loop*************************************************************
void loop(){
Bluetoothstate();                                       // Bluetoothstatus abfragen
menuset();                                              // Menü ausführen
LCDBeschriftung();                                      // LCD Beschriftung ausführen
RXTXBeschriftung();                                     // RX TX Statusbeschriftung ausführen
calculateFrequency();                                   // Frequenzberechnung ausführen
read_RXfreq();                                          // RX Frequenz lesen ausführen
if (VFOAfreq > VFOBfreq){                               // nur wenn VFOAfreq > VFOBfreq ist
  print_RXfreq1();                                      // RX Frequenz am Display schreiben
  print_TXfreq1();                                      // TX Frequenz am Display schreiben
  VFOB_nachziehen1();                                   // VFOB nachziehen ausführen
}
if (VFOAfreq < VFOBfreq){                               // nur wenn VFOAfreq < VFOBfreq ist
  print_RXfreq2();                                      // RX Frequenz am Display schreiben
  print_TXfreq2();                                      // TX Frequenz am Display schreiben
  VFOB_nachziehen2();                                   // VFOB nachziehen ausführen
}
software_reset();                                       // Software Reset ausführen
delay(10);                                              // Verzögerung


/*
Serial.print("VFOAfreq  ");                             // nur für Testzwecke
Serial.println(VFOAfreq);                               // nur für Testzwecke
Serial.print("VFOBfreq  ");                             // nur für Testzwecke
Serial.println(VFOBfreq);                               // nur für Testzwecke
Serial.print("freqmem   ");                             // nur für Testzwecke
Serial.println(freqmem);                                // nur für Testzwecke
Serial.print("freq      ");                             // nur für Testzwecke
Serial.println(freq);                                   // nur für Testzwecke
Serial.println("-------------------");                  // nur für Testzwecke
*/
}
VFOA VFOB
SAT RX SAT TX Shift uint32
10.489.750.000 2.400.250.000 8.089.500.000 max. 4.294.967.295
OSZ OSZ
10.054.000.000 2.256.000.000
ZF
435.750.000 144.250.000
Berechnete TX ZF
144.250.000 RXZF+RXOsz-Shift-TXOsz
VFOA VFOB
SAT RX SAT TX Shift
10.489.750.000 2.400.250.000 8.089.500.000
OSZ OSZ
10.345.000.000 1.965.000.000
ZF
144.750.000 435.250.000
Berechnete TX ZF
435.250.000 RXZF+RXOsz-Shift-TXOsz
VFOA VFOB
SAT RX SAT TX Shift
10.489.750.000 2.400.250.000 8.089.500.000
OSZ OSZ
10.461.000.000 2.349.000.000
ZF
28.750.000 51.250.000
Berechnete TX ZF
51.250.000 RXZF+RXOsz-Shift-TXOsz
VFOA VFOB
SAT RX SAT TX Shift
10.489.750.000 2.400.250.000 8.089.500.000
OSZ OSZ
10.438.000.000 2.372.000.000
ZF
51.750.000 28.250.000
Berechnete TX ZF
28.250.000 RXZF+RXOsz-Shift-TXOsz

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir