Since 08.08.2014 Counts only, if "DNT = disabled".
Your IP is 18.191.134.241 ec2-18-191-134-241.us-east-2
Info
เราจะทำแบบวิศวกรผู้ยิ่งใหญ่
22. February 2025
YOU RATED THIS ...
avg = 0.0 , n = 0
Natalie and Nat King Cole "Unforgettable" 1992
LIMITATIONS
Due to our Software License we must not allow to use the Target 3001 File for commercial use ! Target 3001 Website
LMK61E2.php 29225 Bytes 06-07-2024 22:08:01
The LMK61E2 (TI) • Macromod VHF Synthesizer
A 10 ... 850 MHz (LVPECL) I2C programmeable Synthesizer
The LMK61E2 has almost the same pinout and form-factor as the widespread Si-570. But there is only one output divider
and it looks, that this 10 ms freezing thing was also considered unnecessary. Let's have a closer look at that thing ...
The LMK61E2 on the Shield using the LVPECL outputs ...
✈ Motivation and Circuit Description
This shield was designed to be able to compare it to the Si-570 (SiLabs)
• Micromod RF Synthesizer Shield and to finally have a nice Synthesiser. We therefore put the same attenuator and lowpass on the shield.
The external amplifier of the Si-570 was even integrated. As the LMK61E2 is very power-hungry, a step down converter reduces the dissipated heat.
As the Arduino/Genuino UNO is a 5 Volt system, we used two BSS183 to shift the levels of the SCL and SDA lines. An Si7661 generates -5V from the +5V
to supply the attenuator, a MAAD-007086 which was chosen for its diy friendly form-factor. Last but not least is a GVA-81+ from Mini Circuits.
It has a gain of 10 dB and delivers approx. 8 dBm at the upper end (850 MHz).
✈ What's inside the LMK61E2 ?
The "Ultra-Low Noise" is achieved with mainly two tricks. First the use of a low noise vco and second, the use of frequency dividers.
As the minimum value is 5, this will lower the phase noise by at least 20 * log10 (5) = 14 dB. This is in the hp8640 class - just 60 dB cheaper.
Building blocks of the LMK61E2. Drawing courtesy of Texas Instruments.
✈ Performance
The device has been programmed to 100.000 MHz, + 7dBm in order to compare it to the Si570. Both measurements look identical !
Si570LMK61E2
Obviously we need some more sophisticated measurement gear ... like the E5052 :-)
Si570LMK61E2
Now the difference becomes obvious. Maybe SiLabs should not have left this capacitor away ???
✈ Arduino Sketch - The Code
Double click on code to select ...
/* //////////////////////////////////////////////////////////////////
ARDUINO/Genuino (UNO) LMK61E2 Evaluation Board - Macromod Synthesizer
https://www.changpuak.ch/electronics/LMK61E2.php
Software Version 2.0, USES TIMER INTERRUPT
24.01.2018 by ALEXANDER SSE FRANK
SOME ROUTINES ARE FROM JOËL STEINEMANN
////////////////////////////////////////////////////////////////// */
// LCD PINS (NOKIA5110)
#define RST 13
#define CE 12
#define DC 9
#define DIN 11
#define CLK 10
char string[8];
#include <EEPROM.h>
#include <Wire.h>
#include <stdlib.h>
#include "font.h";
#include "TimerOne.h"
// /////////////////////////////////////////////////////////////
// CONSTANTS FOR THE LMK61E2
const int LMK61E2ADR = 0x59 ;
const float MaxFreq = 890.0 ;
const float MinFreq = 10.0 ;
float Frequency = 100.000 ;
const float REF = 100.00000 ; // Doubler Enabled :-)
byte Reg[73] ;
// /////////////////////////////////////////////////////////////
//VARIABLES AND PIN DEFINITION FOR THE ATTENUATOR
const float LevelMin = -35 ;
const float LevelMax = 15 ;
int Level = 15 ;
const int ATT32 = 7;
const int ATT16 = 6;
const int ATT08 = 5;
const int ATT04 = 4;
const int ATT02 = 3;
const int ATT01 = 2;
// /////////////////////////////////////////////////////////////
unsigned int CursorPosition = 2;
unsigned int CursorOFFtime = 0;
unsigned int AuxKnobEval = 0x00;
float EncoderValue;
boolean EncoderState;
unsigned long currentmillis;
unsigned long LcdMillis;
unsigned long lastchange;
boolean laststate = true;
boolean LcdState = true;
int x=12,y=2;
boolean Frequency_Level = true;
float Max, Min, Addition = 1,maxNr,minNr;
float FR;
// /////////////////////////////////////////////////////////////
// INTERRUPT VARIABLES
volatile unsigned int RotaryEncoderStatus = 0;
volatile unsigned int RotaryEncoderStatusOld = 0;
volatile unsigned int RotaryEncoderActivity = 1 ;
// /////////////////////////////////////////////////////////////
// serial data input
char inputcmd[100];
int cmdindex=0;
// /////////////////////////////////////////////////////////////
void LcdWriteString(char *characters)
{
while(*characters) LcdWriteCharacter(*characters++);
}
void LcdWriteData(byte data)
{
digitalWrite(DC, HIGH);
digitalWrite(CE, LOW);
shiftOut(DIN, CLK, MSBFIRST, data);
digitalWrite(CE, HIGH);
}
void LcdWriteCmd(byte cmd)
{
digitalWrite(DC, LOW);
digitalWrite(CE, LOW);
shiftOut(DIN, CLK, MSBFIRST, cmd);
digitalWrite(CE, HIGH);
}
void LcdWriteCharacter(byte character)
{
for(int i=0; i<5; i++) LcdWriteData(ASCII[character - 0x20][i]);
LcdWriteData(0x00); // 1 pixel distance
}
void LcdWriteBigCharacter(byte character)
{
// HEIGHT AND WIDTH IS DOUBLED, 1 pix >> 4 pix
for(int i=0; i<5; i++) LcdWriteData(ASCII[character - 0x20][i]);
LcdWriteData(0x00); // 1 pixel distance
}
void LcdDisplay(byte data)
{
byte UpperNibble = (data & 0xF0) >> 4 ;
byte LowerNibble = data & 0x0F ;
if (UpperNibble < 0x0A) LcdWriteCharacter(UpperNibble + 0x30);
if (UpperNibble >= 0x0A) LcdWriteCharacter(UpperNibble + 0x41 - 0x0A);
if (LowerNibble < 0x0A) LcdWriteCharacter(LowerNibble + 0x30);
if (LowerNibble >= 0x0A) LcdWriteCharacter(LowerNibble + 0x41 - 0x0A);
}
void LcdClearScreen()
{
for (int i=0; i<504; i++) LcdWriteData(0x00) ;
}
void LcdGoToXY(int x, int y)
{
LcdWriteCmd(0x80 | x); // COL
LcdWriteCmd(0x40 | y); // ROW
}
void LcdBlink(int x, int y)
{
if(RotaryEncoderActivity == 0x00) // Encoder pressed or rotated
{
if(millis() - LcdMillis >= 1000)
{
LcdMillis = millis();
if(LcdState)
{
LcdState = !LcdState;
LcdGoToXY(x,y);
LcdWriteString(" ");
}
else
{
if(Frequency_Level) UpDateFreqLCD();
else UpDateLevelLCD();
LcdState = !LcdState;
}
}
}
}
void UpDateFreqLCD() {
LcdGoToXY(0,0);
LcdWriteString("FREQUENCY");
LcdGoToXY(0,2);
// 3 integers + 1 decimal point + 3 fractionals = 7 characters
LcdWriteString(dtostrf(Frequency,7,3,string));
LcdWriteString(" MHz ");
}
void UpDateLevelLCD() {
LcdGoToXY(0,4);
LcdWriteString("LEVEL ");
if (Level > 0) LcdWriteString("+");
if ((Level <= 0)&& (Level > -10)) LcdWriteString(" ");
// 1 sign + 2 integers + 0 decimal point + 0 fractionals = 1+2 characters
LcdWriteString(dtostrf(Level,2,0,string));
LcdWriteString(" dBm ");
}
void UpDateCursorPosition()
{
// CHANGE THE CURSORPOSITION
if (Frequency_Level)// CHECK WHERE IT STANDS NOW(FREQUENCY OR LEVEL)
{
CursorPosition = CursorPosition + 1; // INCREAS CURSORPOSITION
if ( CursorPosition > 5 ) CursorPosition = 0 ;
}
else CursorPosition = 2;
switch(CursorPosition)
{
case 0:
Addition = 100.0; // SET TENS OF MAGNITUDE(10^2)
x = 0; y = 2; // COORDINATES FOR THE BLINKING FUNCTION
break;
case 1:
Addition = 10.0;
x = 6; y = 2; //
break;
case 2:
Addition = 1;
if(Frequency_Level){x = 12; y = 2;}
else{x = 47; y = 4;}
break;
case 3:
Addition = 0.1;
x = 24; y = 2;
break;
case 4:
Addition = 0.01;
x = 30; y = 2;
break;
case 5:
Addition = 0.001;
x = 36; y = 2;
break;
}
}
void UpdateEncoder()
{
/*
¦ A ¦ B ¦
-----------------
¦ 0 ¦ 0 ¦
-----------------
¦¦ ¦ 0 ¦ 1 ¦ -1
¦¦ ----------------- /\
\/ ¦ 1 ¦ 1 ¦ ¦¦
+1 ----------------- ¦¦
¦ 1 ¦ 0 ¦
-----------------
¦ 0 ¦ 0 ¦
-----------------
WHEN AB IS HIGH AND BY THE NEXT ROTATION B GOES HIGH,
THEN THE ENCODER TURNED LEFT.
IF B GOES LOW, THEN IT TURNED RIGTH.
EXACTLY THE OPPOSITE IS TRUE, WHEN AB IS LOW.
*/
//DETECT THE ROTATION OF THE ENCODER AND SET SOME CONSTANTS
switch(RotaryEncoderStatusOld)
{
// AB WERE LOW
case 4:
if ((RotaryEncoderStatus & B0000010) == 0x00)
EncoderValue = EncoderValue + Addition;
else EncoderValue = EncoderValue - Addition;
// STOPS COUNTING IF THE VALUE IS BIGGER THEN MAX OR LOWER THAN MIN
if (EncoderValue > Max) EncoderValue = maxNr;
if (EncoderValue < Min) EncoderValue = minNr;
break;
// AB WERE HIGH
case 14:
if ((RotaryEncoderStatus & B0000010) == 0x00)
EncoderValue = EncoderValue - Addition;
else EncoderValue = EncoderValue + Addition;
// STOPS COUNTING IF THE VALUE IS BIGGER THEN MAX OR LOWER THAN MIN
if (EncoderValue > Max) EncoderValue = maxNr;
if (EncoderValue < Min) EncoderValue = minNr;
break;
}
if (Frequency_Level){Frequency = EncoderValue;
maxNr = Frequency; minNr = Frequency;}
else {Level = EncoderValue; maxNr = Level; minNr = Level; }
}
//SWITCH BETWEEN FREQUENCY AND LEVEL VALUE
void SwitchFreqLevel()
{
// CHECK WHERE IT STANDS NOW
Frequency_Level = !Frequency_Level;
if (Frequency_Level)
{
//SET THE CONSTANTS FOR THE FREQUENCY
EncoderValue = Frequency;
Max = MaxFreq;
Min = MinFreq;
Addition = 1.0;
CursorPosition = 1;
UpDateCursorPosition();
UpDateLevelLCD();
}
else
{
//SET THE CONSTANTS FOR THE ATTENTUATOR LEVEL
EncoderValue = Level;
Max = LevelMax;
Min = LevelMin;
Addition = 1.0;
UpDateCursorPosition();
UpDateFreqLCD();
}
}
// CHECK ROTARY ENCODER (A1...A3)
void CheckRotaryEncoder()
{
RotaryEncoderStatusOld = RotaryEncoderStatus ;
RotaryEncoderStatus = PINC & B00001110 ; // PORT MANIPULATION FOR FAST READ
RotaryEncoderActivity = RotaryEncoderActivity
| (RotaryEncoderStatus ^ RotaryEncoderStatusOld) ;
}
/*
• FVCO = FREF x D x [(INT + NUM/DEN)] where
• FVCO: PLL/VCO Frequency (4.6 GHz to 5.6 GHz)
• FREF: 50 MHz reference input
• D: PLL input frequency doubler, 1=Disabled, 2=Enabled
• DIVIDER = INT + NUM/DEN
• INT: PLL feedback divider integer value (12 bits, 1 to 4095)
• NUM: PLL feedback divider fractional numerator value,
• DEN: PLL feedback divider fractional denominator value
• freq = FVCO / OUTDIV
*/
void SetFrequency(float freq)
{
unsigned int OUTDIV = (int)(5600 / freq ) ; // floor :-)
float FVCO = freq * OUTDIV ;
float DIVIDER = FVCO / REF ;
unsigned int INT = (int)DIVIDER ;
float REST = DIVIDER - INT ;
unsigned int NUM = (int)(REST * 10000);
unsigned int DEN = 10000 ;
// The 9-bit Output Divider
Reg[0x16] = (OUTDIV & 0x100) >> 8 ;
Reg[0x17] = (OUTDIV & 0x0FF) ;
// The 12-bit N integer divider value for PLL
Reg[0x19] = (INT & 0x0F00) >> 8 ;
Reg[0x1A] = (INT & 0x00FF) ;
// The 22-bit Fractional Divider Numerator
Reg[0x1B] = (NUM & 0x03F0000) >> 16 ;
Reg[0x1C] = (NUM & 0x000FF00) >> 8 ;
Reg[0x1D] = (NUM & 0x0000FF) ;
// The 22-bit Fractional Divider Denominator
if (NUM == 0x00)
{
DEN = 0x01 ;
Reg[0x1E] = 0x00 ;
Reg[0x1F] = 0x00 ;
Reg[0x20] = 0x01 ;
}
else
{
Reg[0x1E] = (DEN & 0x03F0000) >> 16 ;
Reg[0x1F] = (DEN & 0x000FF00) >> 8 ;
Reg[0x20] = (DEN & 0x0000FF) ;
}
Wire.beginTransmission(LMK61E2ADR);
Wire.write(0x10);
Wire.write(Reg[0x10]);
Wire.write(Reg[0x11]);
Wire.endTransmission();
Wire.beginTransmission(LMK61E2ADR);
Wire.write(0x15);
Wire.write(Reg[0x15]);
Wire.write(Reg[0x16]);
Wire.write(Reg[0x17]);
Wire.write(Reg[0x18]);
Wire.write(Reg[0x19]);
Wire.endTransmission();
Wire.beginTransmission(LMK61E2ADR);
Wire.write(0x1A);
Wire.write(Reg[0x1A]);
Wire.write(Reg[0x1B]);
Wire.write(Reg[0x1C]);
Wire.write(Reg[0x1D]);
Wire.write(Reg[0x1E]);
Wire.write(Reg[0x1F]);
Wire.endTransmission();
Wire.beginTransmission(LMK61E2ADR);
Wire.write(0x20);
Wire.write(Reg[0x20]);
Wire.write(Reg[0x21]);
Wire.write(Reg[0x22]);
Wire.write(Reg[0x23]);
Wire.write(Reg[0x24]);
Wire.write(Reg[0x25]);
Wire.write(Reg[0x26]);
Wire.write(Reg[0x27]);
Wire.endTransmission();
Wire.beginTransmission(LMK61E2ADR);
Wire.write(0x48);
Wire.write(Reg[0x48]);
Wire.endTransmission();
}
void SerialHexOutput(byte value)
{
Serial.print("0x");
if (value < 0x10) Serial.print("0");
Serial.println(value,HEX);
}
void IDN()
{
Wire.beginTransmission(LMK61E2ADR);
Wire.write(0x00);
Wire.endTransmission();
Wire.requestFrom(LMK61E2ADR,6);
Reg[0] = Wire.read();
Reg[1] = Wire.read();
Reg[2] = Wire.read();
Reg[3] = Wire.read();
Reg[8] = Wire.read();
Reg[9] = Wire.read();
Serial.write("VNDRID R0: "); SerialHexOutput(Reg[0]);
Serial.write("VNDRID R1: "); SerialHexOutput(Reg[1]);
Serial.write("PRODID R2: "); SerialHexOutput(Reg[2]);
Serial.write("REVID R3: "); SerialHexOutput(Reg[3]);
Serial.write("I2CADR R8: "); SerialHexOutput(Reg[8]);
Serial.write("EEREV R9: "); SerialHexOutput(Reg[9]);
}
void SetAttentuator(byte b)
{
/*
ATTENTUATION ¦ C32 ¦ C16 ¦ C8 ¦ C4 ¦ C2 ¦ C1 ¦
---------------------------------------------------------------
LOSS,REFERENCE¦ 0 ¦ 0 ¦ 0 ¦ 0 ¦ 0 ¦ 0 ¦
---------------------------------------------------------------
1 dB ¦ 0 ¦ 0 ¦ 0 ¦ 0 ¦ 0 ¦ 1 ¦
---------------------------------------------------------------
2 dB ¦ 0 ¦ 0 ¦ 0 ¦ 0 ¦ 1 ¦ 0 ¦
---------------------------------------------------------------
4 dB ¦ 0 ¦ 0 ¦ 0 ¦ 1 ¦ 0 ¦ 0 ¦
---------------------------------------------------------------
8 dB ¦ 0 ¦ 0 ¦ 1 ¦ 0 ¦ 0 ¦ 0 ¦
---------------------------------------------------------------
16 dB ¦ 0 ¦ 1 ¦ 0 ¦ 0 ¦ 0 ¦ 0 ¦
---------------------------------------------------------------
32 dB ¦ 1 ¦ 0 ¦ 0 ¦ 0 ¦ 0 ¦ 0 ¦
---------------------------------------------------------------
50 dB ¦ 1 ¦ 1 ¦ 0 ¦ 0 ¦ 1 ¦ 0 ¦
---------------------------------------------------------------
*/
// CHECK IF WE ARE IN THE LEVEL MENU
if(!Frequency_Level)
{
// CHANGE ATTENTUATER LEVEL FROM (-35 -> +15) TO (0 -> +50)
b = ((-b)+15);
if (b & 32) digitalWrite(ATT32, HIGH); else digitalWrite(ATT32, LOW);
if (b & 16) digitalWrite(ATT16, HIGH); else digitalWrite(ATT16, LOW);
if (b & 8) digitalWrite(ATT08, HIGH); else digitalWrite(ATT08, LOW);
if (b & 4) digitalWrite(ATT04, HIGH); else digitalWrite(ATT04, LOW);
if (b & 2) digitalWrite(ATT02, HIGH); else digitalWrite(ATT02, LOW);
if (b & 1) digitalWrite(ATT01, HIGH); else digitalWrite(ATT01, LOW);
}
}
void SaveValues()
{
// CHECK FOR CHANGE OF ROTARY ENCODER
if ( RotaryEncoderActivity > 0x00 )
{
lastchange = millis();
laststate = true;
}
// CHECK IF LAST CHANGE OF ROTARY ENCODER > 20 SECONDS
if(((millis()-lastchange)>20000)&& laststate)
{
// SAVE THE VALUES IN THE EEPROM
if( EEPROM.get(0,FR) != Frequency )EEPROM.put(0,Frequency);
if( EEPROM.get(10,FR) != Level )EEPROM.put(10,Level);
laststate = false;
}
}
/*
void SerialProgramming()
{
char ch;
long int temp;
while (Serial.available())
{
ch=(char)Serial.read();
if (((ch >= '0') && (ch <= '9')) || ((ch >= 'A')
&& (ch <= 'Z'))) inputcmd[cmdindex++]=ch;
if (ch == '\n')
{ // parse command if its a newline
inputcmd[cmdindex]=0; // terminate the string
if ((temp=atol(inputcmd)) > 0)
{
if ((temp<MaxFreq)&&(temp>MinFreq))
SetFrequency(temp);
}
cmdindex=0; // reset command line
}
}
}
*/
void setup() {
Serial.begin(9600);
Wire.begin();
// LCD NOKIA 5110
pinMode(RST, OUTPUT);
pinMode(CE, OUTPUT);
pinMode(DC, OUTPUT);
pinMode(DIN, OUTPUT);
pinMode(CLK, OUTPUT);
digitalWrite(RST, LOW);
digitalWrite(RST, HIGH);
LcdWriteCmd(0x21); // LCD extended commands
LcdWriteCmd(0xB8); // set LCD Vop (contrast)
LcdWriteCmd(0x04); // set temp coefficent
LcdWriteCmd(0x14); // LCD bias mode 1:40
LcdWriteCmd(0x20); // LCD basic commands
LcdWriteCmd(0x0C); // LCD normal video
LcdClearScreen();
// Startup display
LcdGoToXY(0,0); LcdWriteString("MACROMOD UNO");
LcdGoToXY(0,2); LcdWriteString("SOFTWARE V1.1");
LcdGoToXY(0,3); LcdWriteString("HARDWARE V2.0");
LcdGoToXY(0,4); LcdWriteString("24.01.2018");
delay(5000);
LcdClearScreen();
// INIT LMK61E2
// REGISTERS LMK61E2 FOR 200 MHz
Reg[0x10] = 0x00 ; // XO_CAPCTRL_BY1
Reg[0x11] = 0x80 ; // XO_CAPCTRL_BY0
// NO HAVE
Reg[0x15] = 0x01 ; // DIFFCTL
Reg[0x16] = 0x00 ; // OUTDIV_BY1
Reg[0x17] = 0x17 ; // OUTDIV_BY0
// NO HAVE
Reg[0x19] = 0x00 ; // PLL_NDIV_BY1
Reg[0x1A] = 0x2E ; // PLL_NDIV_BY0
Reg[0x1B] = 0x00 ; // PLL_FRACNUM_BY2
Reg[0x1C] = 0x00 ; // PLL_FRACNUM_BY1
Reg[0x1D] = 0x00 ; // PLL_FRACNUM_BY0
Reg[0x1E] = 0x00 ; // PLL_FRACDEN_BY2
Reg[0x1F] = 0x00 ; // PLL_FRACDEN_BY1
Reg[0x20] = 0x01 ; // PLL_FRACDEN_BY0
Reg[0x21] = 0x0F ; // PLL_MASHCTRL
Reg[0x22] = 0x28 ; // PLL_CTRL0
Reg[0x23] = 0x03 ; // PLL_CTRL1
Reg[0x24] = 0x04 ; // PLL_LF_R2
Reg[0x25] = 0x00 ; // PLL_LF_C1
Reg[0x26] = 0x00 ; // PLL_LF_R3
Reg[0x27] = 0x00 ; // PLL_LF_C3
// NO HAVE
Reg[0x2A] = 0x00 ; // PLL_CALCTRL
// NO HAVE
Reg[0x2F] = 0x00 ; // NVMSRC
Reg[0x30] = 0x00 ; // NVMCNT
Reg[0x31] = 0x10 ; // NVMCTL
Reg[0x32] = 0x00 ; // NVMLCRC
Reg[0x33] = 0x00 ; // MEMADR
Reg[0x34] = 0x00 ; // NVMDAT
Reg[0x35] = 0x00 ; // RAMDAT
// NO HAVE
Reg[0x38] = 0x00 ; // NVMUNLK
// NO HAVE
Reg[0x42] = 0x00 ; // INT_LIVE
// NO HAVE
Reg[0x48] = 0x02 ; // SWRST
// ATENUATOR, SET ATTENUATOR TO MAX
pinMode(ATT32, OUTPUT); digitalWrite(ATT32, LOW);
pinMode(ATT16, OUTPUT); digitalWrite(ATT16, LOW);
pinMode(ATT08, OUTPUT); digitalWrite(ATT08, LOW);
pinMode(ATT04, OUTPUT); digitalWrite(ATT04, LOW);
pinMode(ATT02, OUTPUT); digitalWrite(ATT02, LOW);
pinMode(ATT01, OUTPUT); digitalWrite(ATT01, LOW);
// THE ROTARY ENCODER: A1, A2, A3
pinMode(A1, INPUT); digitalWrite(A1,HIGH); // PULLUP
pinMode(A2, INPUT); digitalWrite(A2,HIGH);
pinMode(A3, INPUT); digitalWrite(A3,HIGH);
// ENABLE INTERRUPT FOR PIN ...
Timer1.initialize(1000); // EVERY 1 ms
Timer1.attachInterrupt(CheckRotaryEncoder);
RotaryEncoderStatus = PINC ;
RotaryEncoderStatusOld = RotaryEncoderStatus ;
RotaryEncoderActivity = 0x00;
// Read EEPROM
if(EEPROM.read(15) != 0) // Clear all by the first upload
{
for (int i = 0 ; i < EEPROM.length() ; i++)
{
EEPROM.write(i, 0);
}
EEPROM.put(0,Frequency);
EEPROM.put(10,Level);
}
else
{
EEPROM.get(0,Frequency);
EEPROM.get(10,Level);
}
Max = MaxFreq;
Min = MinFreq;
EncoderValue = Frequency;
Addition = 0;
// Set to saved values
SetFrequency(Frequency);
SetAttentuator(Level);
UpDateFreqLCD();
UpDateLevelLCD();
}
void loop()
{
// EVALUATE KNOB PRESSED, BIT 3, TOGGLE
if (RotaryEncoderActivity == 0x04)
{
// FALLING EDGE ONLY
if (( RotaryEncoderStatus & B00000100 ) == 0x00)
{
currentmillis = millis();
EncoderState = true;
}
}
// CHECK IF THE KNOB WAS PRESSED AND HOLDED FOR LONGER
// THAN 1.5 SECONDS.(PRESS AND HOLD)
if ((( RotaryEncoderStatus & B00000100 ) == 0x00)&&(millis()
- currentmillis >= 1500)&&EncoderState)// FALLING EDGE ONLY
{
// CHANGE BETWEEN FREQUENCY AND ATTENTUATOR LEVEL
SwitchFreqLevel();
EncoderState = false;
}
//CHECK IF THE KNOB WAS PRESSED LONGER THAN 0.1 SECONDS.(SINGLE PRESS)
if ((( RotaryEncoderStatus & B00000100 ) != 0x00)&&(millis()
- currentmillis >= 0.1)&&EncoderState)// RISING EDGE ONLY
{
UpDateCursorPosition();
EncoderState = false;
}
// CHECK FOR CHANGE OF ROTARY ENCODER
if ( RotaryEncoderActivity > 0x00 )
{
// EVALUATE KNOB NOT PRESSED
if (( RotaryEncoderStatus & B00000100 ) != 0x00)
{
UpdateEncoder();
UpDateFreqLCD();
UpDateLevelLCD();
SetFrequency(Frequency);
SetAttentuator(Level);
}
}
SaveValues();
LcdBlink(x,y);
RotaryEncoderActivity = 0 ;
if(Addition == 0)Addition = 1;
//SerialProgramming();
delay(1);
}
// /////////////////////////////////////////////////////////////
// END OF FILE.
// /////////////////////////////////////////////////////////////
✈ Downloads
Thank you for scrolling down :-)
And yes, 107.6 MHz is the frequency of RADIO BASILISK
✈ 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 ?