Categories
Statistics
Flag Counter
Since 08.08.2014
Counts only, if "DNT = disabled".

Your IP is 3.16.147.124
ec2-3-16-147-124.us-east-2.c
Info
Valid HTML 4.01 Transitional Creative Commons Lizenzvertrag
rss
เราจะทำแบบวิศวกรผู้ยิ่งใหญ่
We love the King
27. April 2024
Your valuable opinion :
5 stars

Avg. 5.33 from 12 votes.



28. April 1950
Arduino-Shield-ULTRAMOD.php   30810 Bytes    17-07-2018 16:54:09


Arduino/Genuino 9.9 MHz ... 3.2 GHz Synthesiser


Shield "ULTRAMOD", based on the Si564 from SiLabs



This is a shield to evaluate the performance of the Silicon Labs Si564 Synthesiser. Together with a rotary encoder, an OLED display, an attenuator and some amplifying, this forms a fully functional synthesiser. And yes, we use the homebrewer - friendly 7 x 5 mm version :-)



Arduino Shield ULTRAMOD



  FREQUENCY RANGE

  9.9 MHz ... 3.2 GHz (with gap 2.6 - 2.7 GHz)

  FREQUENCY RESOLUTION

  1 Hz

  FREQUENCY ACCURACY

  - 2.8125 ppm (room temperature)

  OUTPUT POWER

  0 dBm ... + 13 dBm (in 0.5 dB steps)

  POWER SUPPLY

  7.5 V, 800 mA





✈ The building Blocks • Functional Description




Arduino Shield ULTRAMOD Block Diagram

The building Blocks of the Si564 - Drawing courtesy of Silicon Labs


The Si564 consists of an fractional pll with a vco running from 10.8 - 13.12 GHz (A Grade). With a selecteable output divider (HSDIV and LSDIV), the Output Frequency spans from 200 kHz up to 3 GHz. As we use an amplifier in our design, the biasing inductor limits the lower cutoff frequency to about 10 MHz (TCBT-14). This also ensures, that the minimum Frequency is above 6.4 MHz and therefore, the LSDIV can be kept at 1 (or 0x00).

The outputs of the Si564 (LVPECL) are combined with an TCM1-83x-1+ from Mini Circuits and then attenuated (in order to adjust the RF-Level) and then amplified by an GALI2+ (16 dB, 13 dBm, 40 mA)

Finally, the signal passes an attenuator SKY12347-362LF from Skyworks. From the available 31.5 dB attenuation range, approx. 20 dB are used for equalisation and the rest is available for attenuation. Therefore, we expect an amplitude in the range of +10 dBm down to 0 dBm.

As this "thing" provides an ultra-low jitter and has a low phase noise clock at any output frequency, it is ideally suited to drive an AOM (Acousto-Optic Modulator).
Our Quantum - Opticians are excited :-)

"The device is user-programmed via simple I2C commands to provide any frequency from 0.2 to 3000 MHz with <1 ppb resolution and maintains exceptionally low jitter for both integer and fractional frequencies across its operating range. The Si564 offers excellent reliability and frequency stability as well as guaranteed aging performance. On-chip power supply filtering provides industry-leading power supply noise rejection, simplifying the task of generating low jitter clocks in noisy systems". (Says the datasheet of the Si564).



Arduino Shield ULTRAMOD

The PCB of this nifty device. Keep it simple was the order of the day ...


The level-shifter (topleft corner) is only used in a 5 V system. When using an Arduino™ Due or Genuino™ Due, a bridge is inserted.

As our valued customers always demand for high power, we added a ZX60-43-S+ (from Mini Circuits) at the output.

Due to the nature of this design, a lot of harmonics are generated. It is wise to foresee a lowpass filter for your application.


Arduino Shield ULTRAMOD

View inside. A ZX60-43-S+ is addesd to have "some" more power.




✈ Performance




Spectrum ULTRAMOD

Spectrum at 1500 MHz, + 13 dBm


The spectrum looks very clean, even so we have a fractional pll, there are no spurious artefacts visible. (Maybe we should reduce the RBW :-)

The frequency accuracy was - 2.8125 ppm (measured at 3.2 GHz) at room temperature. If you want to improve this, the chip has to be cooled down (in order to get the frequency up). You may also want to measure the temperature (close to the chip) and introduce some calibration factor in your frequency calculation.

It is also very likely, that a frequency error was introduced by a rounding error on the LSB of the fractional part ...




✈ Downloads








✈ Arduino Sketch - The Code



Double click on code to select ...


/* ////////////////////////////////////////////////////////////////// 
ARDUINO/Genuino (DUE) Si564 Evaluation Board - "Ultramod Synthesizer"
https://changpuak.ch/electronics/Arduino-Shield-ULTRAMOD.php
Software Version 2.0 
29.09.2018 by ALEXANDER SSE FRANK
NOTE: USE ARDUINO DUE TO HAVE 64 BIT PRECISION
NOTE: WE USE WIRE1 HERE !
NOTE: YOU HAVE TO CHANGE hardware/arduino/sam/libraries/Wire/Wire.h
THE NEW VALUE OF TWI_CLOCK = 400000;
AS DESCRIBED HERE : http://forum.arduino.cc/index.php?topic=137588.0
////////////////////////////////////////////////////////////////// */


// OLED 128x64 with SH1106 Controller
// E.G. DM-OLED13-625
#define OLED_MOSI  4
#define OLED_CLK   3
#define OLED_DC    6
#define OLED_CS    7
#define OLED_RESET 5


// STATE OF THE ROTARY ENCODER
const int RE2 = A3 ;  // PRESSED
const int RE1 = A2 ;
const int RE0 = A1 ;
unsigned int RE_now = 0;
unsigned int RE_old = 0;
unsigned int RE_xor = 0 ;
unsigned int RE_one = 0 ;
unsigned int RE_two = 0 ;
unsigned int RE_eval = 0x0 ;  // 0 = LEFT(-), 1=RIGHT(+), 2=PRESSED
unsigned long RE_time0 = 0 ;
unsigned long RE_time1 = 0 ;
unsigned long RE_time2 = 0 ;

unsigned long StartMilli ;
unsigned long DurationMilli ;
boolean PressedLong = false ;

// SI564 VARIABLES / CONSTANTS
unsigned long long F_VCO_MIN = 10800000000 ;
unsigned long long F_VCO_MAX = 13122222022 ;
unsigned long long F_OUT_MIN = 19999999 ;
unsigned long long F_OUT_MAX = 2500000001 ;
unsigned long long F_OUT = 2000000000 ;   
float FREQ = 0.0 ;  // FOR DISPLAY
const byte Si564_Address = 0x55 ;

// ATTENUATOR SKY12347-362LF
const int LE = 10 ;
const int CLK = 8;
const int DAT = 9;
float AMPL_MAX = 13.0 ;
float AMPL_MIN = AMPL_MAX - 17.5 ; 
// 31.5 is total attenuator range
// 14 dB is slope compensation
// REMAINING 17.5 dB
float AMPL_EXT = 0.0 ; // dB
float LACT = 7.0 ;     // LEVEL ACTUAL
float CAL[27];


// Menue Item to be displayed
unsigned int MenueItem = 0 ;
unsigned int ActiveDisplay = 0 ;  // FREQUENCY
boolean ShowCursor = true ;
unsigned int CursorPosition = 1 ;


#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH1106.h>

Adafruit_SH1106 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

#if (SH1106_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SH1106.h!");
#endif


 
void setup() 
{
  delay(1999);
  // KNOB - ROTARY ENCODER
  pinMode(RE2, INPUT_PULLUP);
  pinMode(RE1, INPUT_PULLUP);
  pinMode(RE0, INPUT_PULLUP);
  
  Serial.begin(115200);
  Wire1.begin();

  pinMode(LE, OUTPUT);
  pinMode(CLK, OUTPUT);
  pinMode(DAT, OUTPUT);
  digitalWrite(LE, HIGH);

  // THIS IS THE CALCULATED ATTENUATION
  // TO HAVE -20dBm AT INPUT OF THE GALI-2
  // AN EXTERNAL AMPLIFIER IS USED
  CAL[0] = 14.19 ; // AT 20.0 MHz
  CAL[1] = 14.0  ; // AT 100 MHz
  CAL[2] = 14.0  ; // AT 200 MHz
  CAL[3] = 13.70 ; // AT 300 MHz
  CAL[4] = 13.40 ; // AT 400 MHz
  CAL[5] = 13.30 ; // AT 500 MHz
  CAL[6] = 13.1  ; // AT 600 MHz
  CAL[7] = 12.5  ; // AT 700 MHz
  CAL[8] = 12.0  ; // AT 800 MHz
  CAL[9] = 11.35 ;  // AT 900 MHz
  CAL[10] = 10.7 ; // AT 1000 MHz
  CAL[11] = 9.70 ; // AT 1100 MHz
  CAL[12] = 8.90 ; // AT 1200 MHz
  CAL[13] = 8.0  ; // AT 1300 MHz 
  CAL[14] = 7.10 ; // AT 1400 MHz
  CAL[15] = 6.20 ; // AT 1500 MHz
  CAL[16] = 5.3  ; // AT 1600 MHz
  CAL[17] = 4.6  ; // AT 1700 MHz
  CAL[18] = 3.9  ; // AT 1800 MHz
  CAL[19] = 3.1 ;  // AT 1900 MHz
  CAL[20] = 2.4 ; // AT 2000 MHz
  CAL[21] = 1.8 ; // AT 2100 MHz
  CAL[22] = 1.2 ; // AT 2200 MHz
  CAL[23] = 0.7 ; // AT 2300 MHz 
  CAL[24] = 0.0 ; // AT 2400 MHz
  CAL[25] = 0.0 ; // AT 2500 MHz
  CAL[26] = 0.0 ; // AT 2600 MHz

  UpdateFreq(F_OUT);   
  SetRFLevel(LACT, F_OUT);
  
  // INIT OLED
  display.begin(SH1106_SWITCHCAPVCC);
  // SHOW STARTUP SCREEN
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.println("Ultramod");
  display.setTextSize(1);
  display.setCursor(0,21);
  display.println("AN UHF SYNTHESISER");
  display.setCursor(0,33);
  display.println("BASED ON THE SI 564");
  display.setCursor(0,45);
  display.println("(C) ETH QUANTUMOPTICS");
  display.setCursor(0,57);
  display.println("BUILT 31.07.2018");
  display.display();
  delay(9999);
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.println("Ultramod");
  display.setTextSize(1);
  display.setCursor(0,21);
  display.println("FIRMWARE WRITTEN BY");
  display.setCursor(0,33);
  display.println("MR. JOEL STEINEMANN");
  display.setCursor(0,45);
  display.println("MR. MIRCO DILL");
  display.setCursor(0,57);
  display.println("MR. ALEXANDER FRANK");
  display.display();
  delay(9999);
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.println("Ultramod");
  display.setTextSize(1);
  display.setCursor(0,21);
  display.println("HARDWARE DESIGNED BY");
  display.setCursor(0,33);
  display.println("MR. ALEXANDER FRANK");
  display.setCursor(0,45);
  display.println("MR. MANUEL LOPEZ");
  display.setCursor(0,57);
  display.println("MR. TILMAN ESSLINGER");
  display.display();
  delay(9999);
 
}
  
void loop()
{
  switch (MenueItem)
  {
    case 0:
      ShowFrequencyMenue() ;
      ActiveDisplay = 0 ;
      MenueItem = 2 ;
      UpdateFreq(F_OUT);
      // MAYBE THE NEW FREQUENCY DEMANDS AN AMPLITUDE CORRECTION
      SetRFLevel(LACT, F_OUT);
      break;

    case 1:
      ShowAmplitudeMenue() ;
      ActiveDisplay = 1 ;
      MenueItem = 2 ;
      SetRFLevel(LACT, F_OUT);
      break;

    case 2:
      // //////////////////////////////////////////////////////////////
      // READ THE ROTARY ENCODER EVERY 1 ms
      // Timer Interrupt does not work here
      // //////////////////////////////////////////////////////////////
      RE_xor = 0x00 ;
      while (RE_xor == 0x00)
      {
        // WAITING FOR ACTION
        CheckRE() ;
        // delay(1) ;
      }
      RE_time0 = millis();
      RE_one = RE_xor ;
      delay(5);
      // NOW WAIT FOR SOME MORE ACTION ...
      RE_xor = 0x00 ;
      while (RE_xor == 0x00)
      {
        CheckRE() ;
        // delay(1) ;
      }
      RE_time1 = millis();
      RE_two = RE_xor ;
      // TIME DURATION
      RE_time2 = RE_time1 - RE_time0 ;
      PressedLong = false ;
      if (RE_time2 > 999 ) PressedLong = true ;
      // NOW EVALUATE
      Serial.print("RE_one : ");Serial.println(RE_one);
      Serial.print("RE_two : ");Serial.println(RE_two);
      Serial.print("RE_time2 : ");Serial.println(RE_time2);
      RE_eval = 0xFF ;
      if ((RE_one == 0x1) & (RE_two == 0x2)) RE_eval = 0x1;  // RIGHT
      if ((RE_one == 0x2) & (RE_two == 0x1)) RE_eval = 0x0;  // LEFT
      if ((RE_one == 0x4) | (RE_two == 0x4)) RE_eval = 0x2;  // PRESSED

      // //////////////////////////////////////////////////////////////
      // ROTATION = LEFT = -
      // //////////////////////////////////////////////////////////////
      if ((RE_eval == 0x0) && (ActiveDisplay == 0))
        {
          switch (CursorPosition)
          {
            case 0: // -1 GHZ
              if (F_OUT > (F_OUT_MIN + 1E9)) F_OUT -= 1E9 ;
              break;
            case 1: // -100 MHz
              if (F_OUT > (F_OUT_MIN + 1E8)) F_OUT -= 1E8 ;
              break;
            case 2: // -10 MHz
              if (F_OUT > (F_OUT_MIN + 1E7)) F_OUT -= 1E7 ;
              break;
            case 3: // -1 MHz
              if (F_OUT > (F_OUT_MIN + 1E6)) F_OUT -= 1E6 ;
              break;
            case 4: // -100 kHz
              if (F_OUT > (F_OUT_MIN + 1E5)) F_OUT -= 1E5 ;
              break;
            case 5: // -10 kHz
              if (F_OUT > (F_OUT_MIN + 1E4)) F_OUT -= 1E4 ;
              break;
            case 6: // -1 kHz
              if (F_OUT > (F_OUT_MIN + 1E3)) F_OUT -= 1E3 ;
              break;
            case 7: // -100 Hz
              if (F_OUT > (F_OUT_MIN + 1E2)) F_OUT -= 1E2 ;
              break;
            case 8: // -10 Hz
              if (F_OUT > (F_OUT_MIN + 1E1)) F_OUT -= 1E1 ;
              break;
            case 9: // -1 Hz
              if (F_OUT > (F_OUT_MIN + 1E0)) F_OUT -= 1E0 ;
              break;
          }
          MenueItem = ActiveDisplay ;
        }
      // //////////////////////////////////////////////////////////////
      // ROTATION = LEFT = -
      // //////////////////////////////////////////////////////////////
      if ((RE_eval == 0x0) && (ActiveDisplay == 1))
        {
          // DECREASE LEVEL
          LACT -= 0.5 ;
          if (LACT < AMPL_MIN) LACT = AMPL_MIN ;
          MenueItem = ActiveDisplay ;
        }
      // //////////////////////////////////////////////////////////////
      // ROTATION = RIGHT = +
      // //////////////////////////////////////////////////////////////
      if ((RE_eval == 0x1) && (ActiveDisplay == 0))
        {
          switch (CursorPosition)
          {
            case 0: // +1 GHZ
              if (F_OUT < (F_OUT_MAX - 1E9)) F_OUT += 1E9 ;
              break;
            case 1: // +100 MHz
              if (F_OUT < (F_OUT_MAX - 1E8)) F_OUT += 1E8 ;
              break;
            case 2: // +10 MHz
              if (F_OUT < (F_OUT_MAX - 1E7)) F_OUT += 1E7 ;
              break;
            case 3: // +1 MHz
              if (F_OUT < (F_OUT_MAX - 1E6)) F_OUT += 1E6 ;
              break;
            case 4: // +100 kHz
              if (F_OUT < (F_OUT_MAX - 1E5)) F_OUT += 1E5 ;
              break;
            case 5: // +10 kHz
              if (F_OUT < (F_OUT_MAX - 1E4)) F_OUT += 1E4 ;
              break;
            case 6: // +1 kHz
              if (F_OUT < (F_OUT_MAX - 1E3)) F_OUT += 1E3 ;
              break;
            case 7: // +100 Hz
              if (F_OUT < (F_OUT_MAX - 1E2)) F_OUT += 1E2 ;
              break;
            case 8: // +10 Hz
              if (F_OUT < (F_OUT_MAX - 1E1)) F_OUT += 1E1 ;
              break;
            case 9: // +1 Hz
              if (F_OUT < (F_OUT_MAX - 1E0)) F_OUT += 1E0 ;
              break;
          }
          MenueItem = ActiveDisplay ;
        }
      // //////////////////////////////////////////////////////////////
      // ROTATION = RIGHT = +
      // //////////////////////////////////////////////////////////////
      if ((RE_eval == 0x1) && (ActiveDisplay == 1))
        {
          // INCREASE LEVEL
          LACT += 0.5 ;
          if (LACT > AMPL_MAX) LACT = AMPL_MAX ;
          MenueItem = ActiveDisplay ;
        }
      // //////////////////////////////////////////////////////////////
      // ROTARY ENCODER WAS PRESSED
      // //////////////////////////////////////////////////////////////
      if (RE_eval == 0x2)
        {
          // CASE 1 : FREQUENCY MODE AND SHORT PRESS
          if ((ActiveDisplay == 0) && !PressedLong)
          {
            // MOVE CURSOR ONE POSITION RIGHT
            CursorPosition += 1;
            if (CursorPosition > 9) CursorPosition = 0 ;
            MenueItem = ActiveDisplay ;
          }
          // CASE 2 : FREQUENCY MODE AND LONG PRESS
          else if ((ActiveDisplay == 0) && PressedLong)
          {
            // SWITCH TO AMPLITUDE MODE
            ActiveDisplay = 1 ;
            MenueItem = ActiveDisplay ;
          }
          // CASE 3 : AMPLITUDE MODE AND SHORT PRESS
          else if ((ActiveDisplay == 1) && !PressedLong)
          {
            // NOTHING TO DO HERE
            delay(1);
          }
          // CASE 4 : AMPLITUDE MODE AND LONG PRESS
          else if ((ActiveDisplay == 1) && PressedLong)
          {
            // SWITCH TO FREQUENCY MODE
            ActiveDisplay = 0 ;
            MenueItem = ActiveDisplay ;
          }
        }
      break;

    default:
      delay(1);
      break;
  }
  
}


void UpdateFreq( unsigned long long F_OUT) 
{
  // NOTE: SIMPLIFIED CALCULATIONS, AS F_MIN > 6.4 MHz, 
  // LSDIV IS ALWAYS 1, 0x00

  if (F_OUT < F_OUT_MIN) F_OUT = F_OUT_MIN ;
  if (F_OUT > F_OUT_MAX) F_OUT = F_OUT_MAX ;
  FREQ = (float)F_OUT ;
  
  byte Aux = 0x00 ;
  unsigned long HSDIV ;
  unsigned long XTAL = 152600000 ; // Hz
  double FBDIV ;
  unsigned long INTEGER ;
  unsigned long long FRACTION ;
  unsigned long long F_VCO ;
  FBDIV = (double)(F_VCO_MIN * 1.0 / F_OUT );
  HSDIV = (int)(FBDIV + 0.5) ;  
  if ((HSDIV > 32) && (HSDIV % 2)) HSDIV += 1 ;
  // MIN MAX VALUE
  if (HSDIV < 4) HSDIV = 4 ;
  if (HSDIV > 2046) HSDIV = 2046 ;
  F_VCO = HSDIV * F_OUT ;
  FBDIV = (double)(F_VCO * 1.0 / XTAL) ;
  INTEGER = FBDIV ;   // FLOOR :-)
  FRACTION = 4294967295.0 * (double)(FBDIV - INTEGER) ; 
  // Get Device Ready for Update
  // Set page register to point to page 0
  Si564_Write_Byte( 255, 0x00) ;
  // Disable FCAL override 
  Si564_Write_Byte( 69, 0x00) ;
  // Synchronously disable output
  Si564_Write_Byte( 17, 0x00) ;
  // HSDIV [7:0]
  Aux = HSDIV & 0xFF ; 
  Si564_Write_Byte( 23, Aux) ;
  // LSDIV[2:0]; HSDIV[10:8]
  Aux = (HSDIV >> 8) & 0x07 ; 
  Si564_Write_Byte( 24, Aux) ;
  // FBDIV [7:0]
  Aux = FRACTION & 0xFF ; 
  Si564_Write_Byte( 26, Aux) ;
  // FBDIV [15:8]
  Aux = (FRACTION >> 8 ) & 0xFF ; 
  Si564_Write_Byte( 27, Aux) ;
  // FBDIV [23:16]
  Aux = (FRACTION >> 16 ) & 0xFF ; 
  Si564_Write_Byte( 28, Aux) ;
  // FBDIV [31:24]
  Aux = (FRACTION >> 24 ) & 0xFF ; 
  Si564_Write_Byte( 29, Aux) ;
  // FBDIV [39:32]
  Aux = INTEGER & 0xFF ; 
  Si564_Write_Byte( 30, Aux) ;
  // FBDIV [42:40]
  Aux = (INTEGER >> 8 ) & 0x07 ; 
  Si564_Write_Byte( 31, Aux) ;
  // Start FCAL using new divider values
  Si564_Write_Byte( 7, 0x08) ;
  // Synchronously enable output
  Si564_Write_Byte( 17, 0x01) ;
}

void Si564_Write_Byte( byte Register, byte Value) 
{
  byte Error = 0x00 ;
  Wire1.beginTransmission(Si564_Address);  
  Wire1.write(Register); 
  Wire1.write(Value);                
  Error = Wire1.endTransmission();  
  SerialHexOutput(Value) ; 
  /*
  switch (Error) 
  {
    case 0 : Serial.println("0:success");
    break;
    case 1 : Serial.println("1:data too long to fit in transmit buffer");
    break;
    case 2 : Serial.println("2:received NACK on transmit of address");
    break;
    case 3 : Serial.println("3:received NACK on transmit of data");
    break;
    case 4 : Serial.println("4:other error");
    break;
  }
  */
}

void SerialHexOutput(byte value) 
{
   Serial.print("0x");
   if (value < 0x10) Serial.print("0");
   Serial.println(value,HEX);
}




// /////////////////////////////////////////////////////////////////////
// SUBROUTINES DISPLAY.
// /////////////////////////////////////////////////////////////////////

void ShowFrequencyMenue ()
{
  char str[20];
  sprintf(str, "%10lld", F_OUT);
  int len=strlen(str);
  int offset = 0;
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setTextSize(2);
  display.setCursor(0,0);
  display.println("FREQUENCY");
  for (int i=0; i<10; i++)
  {
    if (i>=0) offset = 0;
    if (i>=1) offset = 5;
    if (i>=4) offset = 10;
    if (i>=7) offset = 15;
    display.setTextColor(WHITE);
    display.setCursor(i*11+offset,20);
    if (i<10-len) display.print(" ");
    else display.print(str[i]);
    if ((ShowCursor) && (CursorPosition == i))
    {
      display.setCursor(i*11+offset,26);
      display.print("_");
    }
  }
  ShowInfo();
  display.display();
}

void ShowAmplitudeMenue ()
{
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setTextSize(2);
  display.setCursor(0,0);
  display.println("AMPLITUDE");
  display.setCursor(0,20);
  if (LACT > 0.0) display.print("+");
  if (LACT == 0.0) display.print(" ");
  display.print(LACT,1);
  display.print(" dBm ");
  ShowInfo();
  display.display();
}

void ShowInfo()
{
  display.drawLine(0, 40, 128, 40, WHITE);
  display.setTextSize(1);
  display.setCursor(0,46);
  display.println("PRESS TO MOVE RIGHT");
  display.setCursor(0,57);
  display.print("ROTATE TO INC/DEC");
}

// CHECK ROTARY ENCODER
void CheckRE()
{
// RE_old = RE_now ;
RE_old = (digitalRead(RE2) << 2)|(digitalRead(RE1) << 1)|digitalRead(RE0);
delay(2);
RE_now = (digitalRead(RE2) << 2)|(digitalRead(RE1) << 1)|digitalRead(RE0);
RE_xor = RE_now ^ RE_old ;
}

// /////////////////////////////////////////////////////////////////////
// SUBROUTINES ATTENUATOR.
// /////////////////////////////////////////////////////////////////////

void SetRFLevel(float Level, unsigned long long FREQ)
{
  unsigned int value ;  
  byte index = FREQ / 100000000 ;
  float CAL_ATT = CAL[index] ;
  if (Level < AMPL_MIN) Level = AMPL_MIN ;
  if (Level > AMPL_MAX) Level = AMPL_MAX ;
  // YES, WE HEARD OF THIS THING CALLED "INTERPOLATION"
  float NecessaryAttenuation = CAL_ATT + (AMPL_MAX - Level);
  value = 64 - 2.0 * NecessaryAttenuation ;
  Serial.print("ATT: ");
  Serial.print(NecessaryAttenuation,2);
  Serial.print(" ... ");
  Serial.println(value,BIN);
  digitalWrite(LE, LOW);
  shiftOut(DAT, CLK, MSBFIRST, value);
  digitalWrite(LE, HIGH);
}


// ///////////////////////////////////////////////////////////// 
// END OF FILE.
// ///////////////////////////////////////////////////////////// 




✈ Credits • Note of Thanks




We would like to thank the staff of Computer Controls AG (Switzerland) for their efforts to supply us (our research group at ETH zürich) with free samples.

ขอขอบพระคุณทุกท่าน.


Better than Christmas :-)

Better than Birthday and Christmas together :-)




✈ YAT • Yet another Note




This project uses the Arduino™ / Genuino™ DUE. First it offers 3.3 V Logic to easily talk to the Si564, second it offers 64-Bit calculations, which make life easier, when dealing with numbers larger than 4294967296 (2^32). If the minimum Frequency is larger than approx. 6.4 MHz the LSDIV needs not to be calculated and can be kept at a value of 1 (0x00). As we use an amplifier which is biased by an TCBT-14+ a lower cut-off frequency of 10 MHz is suggested.

As the FR4 degrades much above 2 GHz and the delivered power by the Si-564 also reduces with increased frequency, we added an external amplifier (ZX60-43-S+, Low Current Amplifier, 0.5 MHz to 4 GHz) to get an almost frequency independent amplitude response.

Even so the datasheet says "provides any frequency from 0.2 to 3000 MHz", we detected a gap from 2.624 - 2.7 GHz (13.12 GHz / 5 and 10.8 GHz / 4) which is caused by the (too small) vco span resulting in non-overlapping sub-ranges.




✈ Share your thoughts



The webmaster does not read these comments regularely. Urgent questions should be send via email. Ads or links to completely uncorrelated things will be removed.


Your Browser says that you allow tracking. Mayst we suggest that you check that DNT thing ?

 
t1 = 6498 d

t2 = 370 ms

★ ★ ★  Copyright © 2006 - 2024 by changpuak.ch  ★ ★ ★

Impressum