/* SevSeg Counter Example
upraveno 2/2026. Verze 1.3 Zmena displeje na 4x7. Ukazuje od 0 do -31.5 vcetne znamenka.
Opraveno nastavoveni modulu PE4302 podle datasheet. ``````
*/
#include <EEPROM.h> // standardni Arduino Library
#include <RotaryEncoder.h>
#include "SevSeg.h"
SevSeg sevseg; //Instantiate a seven segment controller object

bool displayupdate = 1;

// piny pro ovladani PE4302 podle zapojeni v egle
int DATA = A5;  //  PE4302 Data
int CLOCK = A4; //  PE4302 CL
int LE = A3;    //  PE4302 LE

float att = 00, attmax = 315, attmin = 00; // aktualni hranice utlumu

int alast, aval;
// misto pro EEPROM
int eeadr = 10; // zvolena adresa pameti

//piny pro pripojeni encoderu
RotaryEncoder encoder(A0, A1);
//Promenna pro tlacitko encoderu
int sw = 1;
int newPos = 0;
int pos = 0;
int hodnota;
#define duration 50000
int Hod1 = 0;
int Hod2 = 0;
int Hod3 = 0;
int tisk;
int kuk;
//*********************************************************
void setup() {

  pinMode(A2, INPUT);
  Serial.begin(9600);

  pinMode(DATA, OUTPUT); // nastaveni PE4302 vystup
  pinMode(CLOCK, OUTPUT);
  pinMode(LE, OUTPUT);
  digitalWrite(sw, HIGH); // tlacitko

  EEPROM.get(eeadr, att);
  hodnota = att;
  if (isnan(att)) att = 0.0; // nastavi EEPROM na 0 pokud tam neni jina hodnota.
  if (att > attmax) att = attmax;
  if (att < attmin) att = attmin;
  setAttenuator(att);
  delay(30);
  encoder.setPosition(att * 2); //vlozi hodnotu z EEPROM

  byte numDigits = 4;//4
  byte digitPins[] = {12, 13, 10, 11};//
  byte segmentPins[] = {4, 2, 3, 9, 8, 7, 6, 5};
  bool resistorsOnSegments = false; // 'false' means resistors are on digit pins
  byte hardwareConfig = COMMON_ANODE; // See README.md for options
  bool updateWithDelays = false; // Default. Recommended
  bool leadingZeros = false; // Use 'true' if you'd like to keep the leading zeros

  sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments, updateWithDelays, leadingZeros);
  sevseg.setBrightness(90);
}

//****************************************************

void loop() {
  static unsigned long timer = millis();
  //static int deciSeconds = 0;
  int ser, len;
  char buf[10];
  float attinput;
  displayH(kuk);

  if (displayupdate >= 1) { // neue LCD Ausgabe
  }
  //Zkontroluje, zda bylo stisknuto tlacitko enkoderu
  sw = digitalRead(A2);   //zmacknutim zapis do pameti
  if (sw != 1)
  {
    EEPROM.put(eeadr, att);
    Serial.print("saved: ");
    Serial.println(att);
    while (digitalRead(sw) == 0); // ceka na uvolneni tlacitka
    kuk = att * 10;
    displayH(kuk);
    delay(1000);
  }
  //______________________________________________________
  //Precte informace o enkoderu
  static int pos = 0;
  encoder.tick();
  int newPos = encoder.getPosition();//precte pozici

  if (newPos > 63) {
    newPos = newPos - 1;
    encoder.setPosition(63);//zada pozicipokud je >63
  }
  if (newPos < 0) {
    newPos = newPos + 1;
    encoder.setPosition(0);//zada pozicipokud je <0
  }

  // Pokud se pozice zmenila, zobrazi se hodnota na seriovem monitoru
  if (pos != newPos) {
    float hodnota = newPos * 5;
    att = (hodnota) / 10;
    setAttenuator(att);
    Serial.print(hodnota / 10);
    Serial.println();
    pos = newPos;
    kuk = hodnota;
    displayH(kuk);
  }

  //_______________________________________________________________
  alast = aval;
  if (Serial.available() > 0) { // serielle Eingaben ?
    ser = Serial.read();
    if (ser == 'h') {
      Serial.println("help");
      Serial.println(" sx.x: set attentuator. Examples: s1.5 | s0 | s 22.5 | s 31 | s 0.0 ");
      Serial.println(" g: get actual attentuator value");
      Serial.println(" e: write to EEPROM");
      Serial.println(" r: read from EEPROM");
      Serial.println(" v: version");
      Serial.println(" attentuator PE4302");
      Serial.println(" min. frequency 1 MHz");
      Serial.println(" max. frequency 4 GHz");
      Serial.println(" min. attentuation 0 dB");
      Serial.println(" max. attentuation 31.5 dB");
      Serial.println(" attentuator step width 0.5 dB");
    }
    if (ser == 'v') Serial.println("1.30"); // version ?

    if (ser == 'e') {
      EEPROM.put(eeadr, att); // je zapsano do EEPROM ?
      Serial.print("saved: ");
      Serial.println(att);
      delay(1000);
    }
    if (ser == 'r') {
      EEPROM.get(eeadr, att); // aus dem EEPROM lesen ?
      Serial.print("read: ");
      Serial.println(att);
      kuk = att * 10;
      displayH(kuk);
    }
    if (ser == 'g') Serial.println(att); // nastaveno na atenuatoru
    kuk = att * 10;
    displayH(kuk);
    if (ser == 's') { // set attentuation s1.5 | s0 | s 22.5 | s 31 | s 0.0
      Serial.setTimeout(15);
      len = Serial.readBytes(buf, 10);
      if ((len > 2) && (len < 8)) { // co nasleduje ?
        attinput = atof (buf);
        attinput = (round(attinput * 2.0)) / 2.0; // auf .0 und .5 runden
      }
      if ((attinput >= 0.0) && (attinput <= 31.51)) {
        att = attinput;
        setAttenuator(att);
        kuk = att * 10;
        displayH(kuk);
      }
    }
    Serial.setTimeout(500);
  }
}

//**************************************************
void setAttenuator(float attent) {
  // Nastaveni PE4302
  // MSB (C16) ... LSB (C0.5) seriove ulozit do PE4302
  // max. 25kHz nebo vsechno prenest za 0,05 ms.
  // zmeny v algoritmu 12.10.2025
  int i; //  Databit
  int attent2 =  attent * 2 ; //(int)
  if ((attent2 < 0) || (attent2 > 63)) // Je to v rozsahu ?
    return;
  digitalWrite(LE, LOW); // Daten in das Latch eingeben
  digitalWrite(CLOCK, LOW);
  for (int b = 6; b > 0; b--) { // pro 6 Bitu
    i = ((attent2 << 1) >> b) & 0x01;
    digitalWrite(DATA, i); // zapise jeden bit A5
    digitalWrite(CLOCK, HIGH); // zapis Bitu A4
    delayMicroseconds(30);   //zpozdeni ?
    digitalWrite(CLOCK, LOW);
    digitalWrite(DATA, LOW);  //nove ?
  }
  digitalWrite(LE, HIGH); // zapise seriova datat A3
  delayMicroseconds(30);   //zpozdeni ?
  digitalWrite(LE, LOW);  // Ceka na nova data.
}

//---------------------------------------------------------------------------
void displayH(float kuk) {
  tisk = kuk ;

  static unsigned long timer = millis();
  static int deciSeconds = 0;
  sevseg.setNumber(att - (att * 2), 1); //cislo,desetina carka
  sevseg.refreshDisplay(); // Must run repeatedly
}
//____________________________________________________________________________________

/// END ///
