VFO si5351 avec µC Arduino Help!

Bonjour à tous

A l’attention des développeurs C, C++ et Arduino .

Bon je me suis lancé dans la réalisation d’un VFO DDS ,tout fonctionne : codeur incrémental , entrées/sorties , affichage LCD, mise en mémoire EEPROM , excepté la partie du code permettant d’incrémenter en Hz , KHz et MHz .
Tant que c’est en Hz ça marche et ça ne va pas pour avancer par bonds en multiples .Quelqu’un à t’il une idée de code ?
Je veux implémenter le pas par deux boutons un pour augmenter , l’autre pur diminuer .
Pour le moment c’est en Hertz mais pour balayer de 3MHz à 30 MHz par pas de 1 Hz il faudrait que je mette une perceuse sur l’axe du codeur pendant des heures donc ca va pas! :slightly_frowning_face:

Je fournis mon code bien sur

Merci d’avance

Emmanuel F4FIT

Bonjour,
Et ce code, on peut voir la partie concernée?
Déjà, pour changer le pas d’incrément (Hz - kHz - etc) il faut programmer le switch du codeur.
Exemple 1 appui → Hz, 2 appuis → kHz, et ainsi de suite.

J’envois ca de suite!

#include <LiquidCrystal.h>
#include « Wire.h »
#include « si5351.h »
#include<EEPROM.h>
#include"simpleBouton.h"

#define pinArduinoRaccordementSignalSW 2 // pin D2 de l’Arduino ligne SW BP mise en mémoire
#define pinArduinoRaccordementSignalCLK 3 // pin D3 de l’Arduino ligne CLK du codeur
#define pinArduinoRaccordementSignalDT 4 // pin D4 de l’Arduino ligne DT du codeur

int etatPrecedentLigneSW; // Cette variable nous permettra de stocker le dernier état de la ligne SW, afin de le comparer à l’actuel

volatile long compteur = 0; // Incrementation /Decrementation du codeur
long val_mem; // Valeur Frequence mise en mémoire
long step = 1;
long val_affich;
long val_frequency; // Valeur Frequence
long val_freqref = 10000000;
long val_nextctr;
long ctrstepp;

int rs = 12;
int en = 11;
int d4 = 10;
int d5 = 9;
int d6 = 8;
int d7 = 7;

const int numRows = 2; //Nombre de rangées afficheur
const int numCols = 16; //Nombre de colonnes afficheur

LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
simpleBouton bouton_up(5); //pas up
simpleBouton bouton_dn(6); //pas down

/////////////////////////////////////////////////////////////////////////////////////////////////////////

// ========================
// Initialisation programme
// ========================
void setup()
{

lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print("Emmanuel");
lcd.setCursor(0, 1);
lcd.print("18/12/2025");
delay(500);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("INCR: ");
lcd.setCursor(0,1);
lcd.print("FREQ:");

val_affich = EEPROM.get(10, compteur);

// Config  pins de en "entrées" (signaux codeur)
pinMode(pinArduinoRaccordementSignalSW, INPUT);         
pinMode(pinArduinoRaccordementSignalDT, INPUT);
pinMode(pinArduinoRaccordementSignalCLK, INPUT);

etatPrecedentLigneSW  = digitalRead(pinArduinoRaccordementSignalSW);

// Activation d'interruptions sur les lignes CLK et SW
attachInterrupt(digitalPinToInterrupt(pinArduinoRaccordementSignalCLK), changementDetecteSurLigneCLK, FALLING); // FALLING => détecte tout front descendant
attachInterrupt(digitalPinToInterrupt(pinArduinoRaccordementSignalSW), changementDetecteSurLigneSW, CHANGE);    // CHANGE => détecte tout changement d'état

delay(10);

}

////////////////////////////////////////////////////////////////////////////////////////////////////////////

// =================
// Boucle principale
// =================
void loop()

{

                if (bouton_dn) 
                   {
                    ctrstepp = ctrstepp -1; 


                    switch(ctrstepp)
                        {
                        case 1:
                            step = (step/10);
                            //if (ctrstepp < 1) 
                            //ctrstepp = 1;                                
                            lcd.setCursor(7,0);
                            lcd.print("         ");        
                            lcd.setCursor(7,0);
                            lcd.print(step);
                           
                        break;

                        case 2:
                            step = (step/10);
                            //if (ctrstepp < 1) 
                            //ctrstepp = 1;
                            lcd.setCursor(7,0);
                            lcd.print("         ");        
                            lcd.setCursor(7,0);
                            lcd.print(step);
                                   
                        break;

                        case 3:
                            step = (step/10);
                            //if (ctrstepp < 1) 
                            //ctrstepp = 1;                                
                            lcd.setCursor(7,0);
                            lcd.print("         ");        
                            lcd.setCursor(7,0);
                            lcd.print(step);
                                  
                        break;

                        case 4:
                            step = (step/10);
                            //if (ctrstepp < 1) 
                            //ctrstepp = 1;                                
                            lcd.setCursor(7,0);
                            lcd.print("         ");        
                            lcd.setCursor(7,0);
                            lcd.print(step);
                                  
                        break;

                        case 5:
                            step = (step/10);
                            //if (ctrstepp < 1) 
                            //ctrstepp = 1;                                
                            lcd.setCursor(7,0);
                            lcd.print("         ");        
                            lcd.setCursor(7,0);
                            lcd.print(step);
                                 
                        break;
                        }
                   }
               
            //********************************incrémentation step par dizaines*********************** 


                if (bouton_up)  
                    {
                    ctrstepp = ctrstepp + 1;
                    
                                                                                
                    switch(ctrstepp)
                        {
                        case 1:
                            step = (step*1);
                            //if (ctrstepp >10000)
                            //ctrstepp = 10000;                                
                            lcd.setCursor(7,0);
                            lcd.print("         ");        
                            lcd.setCursor(7,0);
                            lcd.print(step);
                                   
                        break;

                        case 2:
                            step = (step*10);
                            //if (ctrstepp >10000)
                            //ctrstepp = 10000;                                
                            lcd.setCursor(7,0);
                            lcd.print("         ");        
                            lcd.setCursor(7,0);
                            lcd.print(step);
                                  
                        break;

                        case 3:
                            step = (step*10);
                            //if (ctrstepp >10000)
                            //ctrstepp = 10000;                                
                            lcd.setCursor(7,0);
                            lcd.print("         ");        
                            lcd.setCursor(7,0);
                            lcd.print(step);
                                  
                        break;

                        case 4:
                            step = (step*10);
                            //if (ctrstepp >10000)
                            //ctrstepp = 10000;                                
                            lcd.setCursor(7,0);
                            lcd.print("         ");        
                            lcd.setCursor(7,0);
                            lcd.print(step);
                                 
                        break;

                        case 5:
                            step = (step*10);
                            //if (ctrstepp >10000)
                            //ctrstepp = 10000;                                
                            lcd.setCursor(7,0);
                            lcd.print("         ");       
                            lcd.setCursor(7,0);
                            lcd.print(step);
                                   
                        break;
                        }
                    }   
                   
                                {
                                val_affich = (compteur + (compteur*(step-1)));
                                //val_affich = (val_affich + step);
                                /*
                                if(val_affich > 1)
                                    {
                                    val_affich= 1;
                                    }


                                if(val_affich>30000000)
                                    {
                                    val_affich= 30000000;
                                    }
                                */
                                lcd.setCursor(5,1);
                                lcd.print("           ");
                                lcd.setCursor(7,1);
                                lcd.print(val_affich);                                            
                                delay(100);       
                                }

}

/////////////////////////////////////////////////////////////////////////////////////////////////
// =====================================================
// Routine d’interruption : changementDetecteSurLigneCLK
// =====================================================
void changementDetecteSurLigneCLK()
{
// Lecture de la ligne DT, issue du codeur
int etatActuelDeLaLigneDT = digitalRead(pinArduinoRaccordementSignalDT);
int etatActuelDeLaLigneCLK = LOW;

                if(etatActuelDeLaLigneCLK != etatActuelDeLaLigneDT) 
                    {
                        compteur++;
                    }

                else
                    {
                        compteur--;  
                    }    
            }

/////////////////////////////////////////////////////////////////////////////////////////////////
// ====================================================
// Routine d’interruption : changementDetecteSurLigneSW
// ====================================================

            void changementDetecteSurLigneSW() 
            {

                int etatActuelDeLaLigneSW = digitalRead(pinArduinoRaccordementSignalSW);
                etatPrecedentLigneSW = etatActuelDeLaLigneSW;
                if(etatActuelDeLaLigneSW == LOW)
                
                EEPROM.put(10,val_affich); 
                delay(500);   
                lcd.clear();
                lcd.setCursor(0,0);
                lcd.print("ENREGISTRE");
                delay(2000);

                
                lcd.clear();
                lcd.setCursor(0,0);
                lcd.print("INCR: ");
                lcd.setCursor(0,1);
                lcd.print("FREQ:");
                */

            }

Ce que je viens d’expliquer avec le switch est déjà dans votre programme

switch(ctrstepp)
{
case 1:
step = (step*1);
//if (ctrstepp >10000)
//ctrstepp = 10000;
lcd.setCursor(7,0);
lcd.print(" ");
lcd.setCursor(7,0);
lcd.print(step);

                    break;

                    case 2:
                        step = (step*10);
                        //if (ctrstepp >10000)
                        //ctrstepp = 10000;                                
                        lcd.setCursor(7,0);
                        lcd.print("         ");        
                        lcd.setCursor(7,0);
                        lcd.print(step);
                              
                    break;

                    case 3:
                        step = (step*10);
                        //if (ctrstepp >10000)
                        //ctrstepp = 10000;                                
                        lcd.setCursor(7,0);
                        lcd.print("         ");        
                        lcd.setCursor(7,0);
                        lcd.print(step);
                              
                    break;

Mais il y a une nouille dans le potage due probablement à un problème de recopie de code car tous les « case2, case3, etc » sont identiques..

J’utilise un codeur incrèmental 100pr sans switch je me sert de l’entrée d’interruption pour la mise en mémoire d’une fréquence sur l’EEPROM .
De plus je ne veux pas copier bêtement du code et du schémas , je veux savoir, construire et maitriser l’ensemble .

Oui c’est identique vu qu’a chaque appuis du BP UP (bouton_up) ou Down (bouton_dn) je reécris la variable (step) en la multipliant ou la divisant par 10.
L’afficheur me confirme bien que cette variable est prise en compte

Bonjour
On parle de ce générateur d’horloge ici :

1 « J'aime »

Bonjour,
Janpolanton a raison, la présence d’un switch case avec des blocs identiques est très étranges.
Simplifiez peut-être déjà le code pour éviter les redondances ce sera plus clair.

Par exemple, votre bloc if(bouton_up) peut être grandement simplifié avec les lignes de codes ci-dessous qui sont équivalentes à ce que vous avez actuellement (désolé je ne parviens pas à indenter …) :

if (bouton_up) {
ctrstepp = ctrstepp + 1;
if (ctrstepp >= 1 && ctrstepp <= 5) {
ctrstepp = (ctrstepp == 1 ? ctrstepp : ctrstepp * 10)
lcd.setCursor(7, 0);
lcd.print(" ");
lcd.setCursor(7, 0);
lcd.print(step);
}
}

Autre chose, on note une dissymétrie entre votre bloc if(bouton_down) et if(bouton_up) ce qui paraît étrange également:

  • Dans le premier cas le step est systématiquement divisé par 10 quelque soit sa valeur entre 1 et 5
  • Dans le second cas, il est conservé lorsqu’il vaut 1 et multiplé par 10 lorsque sa valeur est entre 2 et 5.

Bonjour,

De plus je ne veux pas copier bêtement du code et du schémas , je veux savoir, construire et maitriser l’ensemble .

C’est tout à votre honneur de ne pas pomper de l’existant mais parfois, c’est un gain de temps d’adapter l’existant à sa propre sauce.

Regardez cette réalisation (si vous ne la connaissez pas déjà).

Bon , j’ai modifié le programme :
J’ai mis la sélection de pas (step) sur l’interruption , ça marche un peu mieux mais c’est pas encore ça quand je choisis le pas MHz et que je veux ajuster en revenant sur une valeur inferieure en KHz ou Hz ça me remet la valeur de départ .
Voici ici dans le lien ci dessous la simulation dynamique et le code .
Lien simulateur dynamique
Ça fait exactement pareil sur la maquette réelle .
Merci de votre éventuelle aide .

Emmanuel F4FIT

1 « J'aime »

Je ne connaissais pas ce simulateur, adopté!!!

2 « J'aime »

Bonsoir ,
Malheureusement il ne contient pas toutes les bibliothèques surtout celle exotiques …
Mais ca marche pas mal

1 « J'aime »

J’en ai déjà deux dont j’ai copié collé le programme :
-Un a base d’un PIC 16F84 et d’un AD9851 (qui équipe mon transceiver de construction OM)
-Un autre à base d’Arduino Nano et d’un SI5351 .
Dont je n(ai pour seul mérite d’avoir réalisé la CAO et les PCBs et d’avoir « bourré le crâne » des µContrôleurs avec du copié .
Là je tiens à en réaliser un entièrement de mon cru , la démarche est uniquement pédagogique .
Certains passent la retraite en faisant des mots croisés moi je la passe au fer à souder et à écrire des lignes de code HI ! :slightly_smiling_face:

Merci Georges pour cet article que j’avais déjà parcouru .
Il est intéressant de voir la possibilité de « calmer » les harmoniques par programmation
Mais je pense utiliser des filtres pass-bas commutés en sortie .
Et pour attaquer un mélangeur en anneau il semble que du signal carré soit meilleur .

Meilleures 73

Emmanuel F4FIT

Bonjour,
je connaissais pas non plus.
Quel comportement souhaitez vous obtenir ? pouvez-vous le décrire avec un exemple précis ? Etat de l’afficheur, action sur quel contrôle, affichage souhaité et valeur des variables souhaitée ?

Bonsoir,
Alors , je souhaite par exemple pour choisir une fréquence régler l’incrément au debut sur MHz sélectionner avec le codeur la valeur , ensuite décrémenter en Khz et régler au codeur jusqu’à affiner en Hz ou rester en KHz et parcourir la bande avec le codeur

En fait choisir une fréquence de départ que je pourrais incrémenter ou décrémenter du pas que je veux et parcourir ensuite avec le codeur au pas déterminé

Par exemple je veux aller sur 7882.5 KHz (fréquences cartes Fax météo)
Je choisis incrément MHz je vais jusqu’à 7
Puis increment KHz jusqu’a 7882
Puis passer en Hz pour affiner

Le but étant de limiter le nombre de tours de codeur sinon sur pas Hz il va m’en falloir 290000
pour parcourir de 1MHz à 30MHz (codeur 100 pas par tours et fréquence de début 1MHz)

ok, actuellement lorsque vous changez le pas, la fréquence est changée. Confirmez vous que ce comportement est anormal.

Par exemple on est sur 100 000 Hz le pas est sur 1 Hz, on incrémente on obtient bien 100 001 Hz mais lorsqu’on change le pas en passant à 10 Hz la fréquence affichée change et passe à 100 010 Hz ne devrait-elle pas rester à 100 001 Hz pour ensuite pouvoir être incrémentée par un pas de 10 et passer à 100 011 Hz ?

Exactement ce qui se passe et dont je n’arrive pas à me dépêtrer!