09 aprilie 2024

ADC. Rezolutii si Volti

ADC-urile convertesc eșantioanele unui semnal analogic în valori digitale.

Rezoluția ADC-ului este numărul de biți pe care îl utilizează în vederea digitizării eșantioanelor de intrare. 

Pentru un ADC pe n biți, numărul de niveluri digitale discrete care pot fi produse este 2n. 

Astfel, un digitizor pe 12 biți poate rezolva 212 sau 4096 niveluri. 

Cel mai puțin semnificativ bit (lsb) reprezintă cel mai mic interval care poate fi detectat și, în cazul unui digitizor pe 12 biți, este 1/4096 sau 2,4 x 10-4. 

Pentru a converti lsb într-o tensiune, luăm intervalul de intrare al digitizorului și îl împărțim la doi, ridicat la rezoluția digitizorului.

27 martie 2024

VFO Encoder selection for Xiegu G90

 From time to time someone start searching for part number of the VFO encoder.

Here is a selection of part numbers for encoders without detent (no clicks).

As a personal observation, with more than 18 pulses per revolution it is a pain to use a no detents encoder...

For no detent encoders:


PEC11R-4020K-S0018 with knurled shaft, 20mm lenght, no detents, momentary switch and 18 pulses per revolution.

PEC1R-4025F-S0018 with flatted shaft. From ALPS, EC11E, 20mm long flatted shaft (only) momentary switch.



From ALPS: 

EC11E153440D with 15 pulses per revolution.

EC11E18344Oc with 18 pulses per revolution.


For both producers I reccoment study their product selection datasheets which can be downloaded as pdf clicking on their names.


I usually like to have longer shafts and cut them to my needs so, if you want a shorter one, just check the datasheets for the part number. 

Both are producing compatible encoders for VFO, VOL and FUNCTION. 


23 martie 2024

Simplyfying the code by using a tic-tac machine

Playing with Arduino and it's C++ I often use timed tasks.

Basically, in Arduino you can do things at specific interval either by adding delay() at some strategic points or using wellknown non-blocking code:

const unsigned long interval = 1000; // Interval for LED blink (in milliseconds)
unsigned long previousMillis = 0;    // Variable to store time since last LED update

int ledPin = 13; // Pin for the LED

void setup() {
                    pinMode(ledPin, OUTPUT); // Initialize LED pin as an output

void loop() {

                  unsigned long currentMillis = millis(); // Get the current time

  // Check if it's time to update the LED
  if (currentMillis - previousMillis >= interval) {
                    previousMillis = currentMillis; // Save the last time LED was updated
                    digitalWrite(ledPin, !digitalRead(ledPin)); // Toggle the LED state

      // Other non-blocking tasks can be added here
What if, the code need more than one timer?
Well, we  can use multiple timers like that!
While this is the simple and easy way, in a big code we start loosing track of what does what and if the code is big, each byte counts! Let's not forget that  each unsigned long type variable cost us 4 bytes of precious memory; each byte consists of 8 bits, and an unsigned long on Arduino is a 32-bit data type, so it occupies 4 bytes (32 bits / 8 bits per byte = 4 bytes).
I have a program in which I have to test multiple timers with multiple distinct intervals and the memory cost was huge.
So, I stayed and think and found a very elegant solution.
While I may reinvented the wheel, I think it is nice to share it with you!
It is all about making a single time measuring function and asign boolean variables to keep track of various things.
  unsigned long previousMillis_ONESECOND = 0; // Variable to store the last time the ONESECOND was flipped
  const unsigned long interval_ONESECOND = 1000; // Interval at which to flip the ONESECOND (in milliseconds)
    bool ONESECOND = false;

void loop(){
    updateONESECOND(); }

void updateONESECOND(){
          unsigned long currentMillis = millis(); // Get the current time
          // Check if it's time to flip ONESECOND
          if (currentMillis - previousMillis_ONESECOND >= interval_ONESECOND) {
            // Save the last time ONESECOND was flipped
            previousMillis_ONESECOND = currentMillis;

           // Flip ONESECOND
then, I have other functions that check various conditions AND bool.
For example, a function that blink a special character on a LCD: 
bool ProcessSTART = false;
void fLCD(){  // alternate symbol at a rate of one second while StartLog is activated
            if (ONESECOND && ProcessSTART){
                else {

the other bool ProcessSART is flipped in other part of the program.
In other functions you can count the number of seconds using this tic-tac function and get other intervals derived from it, using less bytes in a simple arithmetic function.
It's like using an external time generator for all the functions in the code.

Most viewed posts in last 30 days