When using this form, your ip is stored in order to avoid multiple voting on the same website. That's it.
August 2026 เรา ❤ แม่
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 04-03-2025 19:13:16
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.