Code source ultra-simpliste pour Arduino/MSP430 d’un VFO à AD9850/AD9851

Prototype kit Balise WSPR DDS XV4Y (http://xv4y NULL.radioclub NULL.jpg)Dans un commentaire Sylvain F6GGX m’a demandé après ce bout de code. Il était disponible gratuitement dans la boutique mais comme j’ai désactivé cette dernière il a disparu du site…
Voici donc le code source d’un VFO très simpliste à base de AD9850/AD9851 qui utilise les librairies que j’ai écrites ou adaptées (http://xv4y NULL.radioclub Honnêtement je pense pas que ce code soit très utile, rien de particulièrement compliqué et l’ergonomie à 4 boutons n’est pas super. C’est utile en dépannage avec le kit balise WSPR que je produisais mais c’est tout. Le code est écrit pour Energia sur MSP430, le porter sur Arduino (ATMega328) ne devrait poser aucun problème.

/* Simple VFO with DDS for MSP430G2553
 * Code for Energia 009
 * By Yannick DEVOS - XV4Y - March 2013

    Copyright 2012-2013 Yannick DEVOS under GPL 3.0 license
    Any commercial use or inclusion in a kit is subject to author approval

 * Agile Frequency generation using AD9850/9851 DDS
 * Output to Nokia 5110 compatible LCD
 * Check if P2_2 has changed state and switch VFO (like when PTT is pressed to operate split)

Usage for short press of buttons :
- Up / Down      increase or decrease the frequency following the choosen digit
- Left / Right   increase or decrease the digit
- OK             validate the frequency and send it to the DDS
Long press of buttons :
- Left           Set the current VFO to the next band bottom frequency
- Right          VFO A = VFO B
- OK             Switch between VFO A and VFO B

Revision history :
v1.00    2013-03-18
         First release

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
GNU General Public License for more details.

You can download a copy of the GNU General Public License at <>

// Here modify to your taste or needs

#define PTT_key          P2_2
#define AUTO_VALID       // Uncomment if you want the DDS frequency to be udapted automatically after each value change

#define DEFAULT_FREQ    8            // Value 8 in Frequencies array is 14000000
// Here under don't touch anything unless you know what you do

#include <legacymsp430.h>
#include <AD9850.h> // Library for AD9850 control by MSP430

#include <LCD_5110.h>

              // Frequencies (1 Hz precision) you can select
const unsigned long int frequencies[] = {
  137000, 471000, 501000, 1830000, 3500000, 5200000, 7000000, 10100000,
  14000000, 18068000, 21000000, 24890000, 28000000, 50000000, 70000000};
const byte Analog_Noise = 5;    // Margins for reading analog buttons

boolean   vfo=0, saved_PTT;  // VFO A or B and PTT input state
char      multiplier, aff_multiplier, freq_select=DEFAULT_FREQ;
unsigned  long int frequency_A=frequencies[DEFAULT_FREQ], frequency_B=frequencies[DEFAULT_FREQ], debounce;

char chaine_txt[6] = {' ', ' ', ' ', ' ', ' ', 0x00};

AD9850 myDDS (P1_0, P1_1, P1_2, P1_4);  // Call the AD9850 Library, AD9850 pins for CLOCK, LOAD, DATA and RESET
//AD9850 myDDS (P1_1, P1_2, P1_0, P1_4);  // Call the AD9850 Library, AD9851 pins for CLOCK, LOAD, DATA and RESET

LCD_5110 myScreen(P2_3,    // Chip Select *
         P1_6,    // Serial Clock *
         P2_5,    // Serial Data *
         P2_4,    // Data/Command *
         NULL,    // Reset *
         P1_7,    // Backlight
         NULL);  // Push Button 0

// Defining pins mode and initializing hardware

void setup() {
  pinMode(PTT_key, INPUT_PULLUP);


  myScreen.text(0, 0, "sVFO");
  myScreen.text(0, 2, "AD9850");
  myScreen.text(0, 4, "v1.00 - XV4Y");
  myScreen.text(0, 5, "Init...");
  myDDS.SetFrequency( frequency_A, 0, false );

  digitalWrite( PTT_key, LOW );


// Here starts the actual sequence sending

void loop() {
    if (vfo == 0) {
      myScreen.text(0, 0, "VFO A");
      myDDS.SetFrequency( frequency_A, 0, false );
    } else {
      myScreen.text(0, 0, "VFO B");
      myDDS.SetFrequency( frequency_B, 0, false );

    display_freq (frequency_A, 3);
    display_freq (frequency_B, 5);

    while (read_buttons()==5 || read_buttons()==4 || read_buttons()==2) delay(10); // Debounce except for UP/DWN

    while (1) {
      // Update the frequencies display
      if (multiplier > 5) {
        aff_multiplier = multiplier + 2;
      } else if (multiplier > 2) {
        aff_multiplier = multiplier + 1;
      } else {
        aff_multiplier = multiplier;
      myScreen.text(0, 4, "          ");
      if (vfo == 0) {
        myScreen.text(9-aff_multiplier, 4, "^");
      } else {
        myScreen.text(9-aff_multiplier, 4, "v");
      display_freq (frequency_A, 3);
      display_freq (frequency_B, 5);
      // Read the analog buttons input
      if(read_buttons()==1) {            // Up we increase frequency
        delay(200);  // Debounce
        if (vfo == 0) {
          frequency_A = frequency_A + powf(10,(float)multiplier);
        } else {
          frequency_B = frequency_B + powf(10,(float)multiplier);
#if defined AUTO_VALID

      } else if (read_buttons()==3) {    // Down we decrease frequency
        delay(200);  // Debounce
        if (vfo == 0) {
          frequency_A = frequency_A - powf(10,(float)multiplier);
        } else {
          frequency_B = frequency_B - powf(10,(float)multiplier);
#if defined AUTO_VALID

      } else if (read_buttons()==2) {    // Left we increase multiplier
        debounce = millis();
        while (read_buttons()==2) {  //Debounce
          if ((millis()-debounce)>1000) {  // Long press we do "Band UP"
            if (freq_select > 14) freq_select = 0;
            if (vfo == 1) frequency_B = frequencies[freq_select]; else frequency_A=frequencies[freq_select];
        if (multiplier > 7) multiplier = 7;

      } else if (read_buttons()==4) {    // Right we decrease multiplier
        debounce = millis();
        while (read_buttons()==4) {  //Debounce
          if ((millis()-debounce)>1000) {  // Long press we do VFO A=B
            if (vfo == 1) frequency_A = frequency_B; else frequency_B=frequency_A;
        if (multiplier < 0) multiplier = 0;

      } else if (read_buttons()==5) {    // OK we go out
        debounce = millis();
        while (read_buttons()==5) {  //Debounce
          if ((millis()-debounce)>1000) {  // Long press we switch VFO A/B
            if (vfo == 1) vfo=0; else vfo=1;
        break;   // Short press we just leave the loop so the frequency is transmitted to the AD9850

      // Check if we are transmitting split (momentaneous VFO A->B switch)
      if (saved_PTT != digitalRead(PTT_key)) {
        saved_PTT = digitalRead(PTT_key);
        if (vfo == 1) vfo=0; else vfo=1;


// Display the frequency
void display_freq (unsigned long freq, char ligne) {
  myScreen.text(10, ligne, " Hz ");
  chaine_txt[5] = 0x00;
  chaine_txt[4] = 0x30 + (((freq)/1)%10);
  chaine_txt[3] = 0x30 + (((freq)/10)%10);
  chaine_txt[2] = 0x30 + (((freq)/100)%10);
  chaine_txt[1] = '.';
  chaine_txt[0] = 0x30 + (((freq)/1000)%10);
  myScreen.text(5, ligne, chaine_txt);
  chaine_txt[5] = 0x00;
  chaine_txt[4] = 0x30 + (((freq)/10000)%10);
  chaine_txt[3] = 0x30 + (((freq)/100000)%10);
  chaine_txt[2] = '.';
  chaine_txt[1] = 0x30 + (((freq)/1000000)%10);
  chaine_txt[0] = 0x30 + (((freq)/10000000)%10);
  myScreen.text(0, ligne, chaine_txt); 

// Display a 2 digits number
void display_number (byte number, char column, char ligne) {
  chaine_txt[2] = 0x00;
  chaine_txt[1] = 0x30 + (number%10);
  chaine_txt[0] = 0x30 + ((number/10)%10);
  myScreen.text(column, ligne, chaine_txt);

// Return a button value depending on the analog reading
byte read_buttons () {
  int value = analogRead(ANALOG_BUTTONS);
  if ( value<(1+Analog_Noise) ) {
    return 1;
  } else if ( value<(78+Analog_Noise) ) {
    return 2;
  } else if ( value<(146+Analog_Noise) ) {
    return 3;
  } else if ( value<(205+Analog_Noise) ) {
    return 4;
  } else if ( value<(255+Analog_Noise) ) {
    return 5;
  } else {
    return 0;

Ampli 100W 630m par IK1HGI

Ampli 630m 472KHz 100W IK1HGI (http://xv4y NULL.radioclub NULL.jpg)Antonio IK1HGI nous propose son amplificateur 100W Moyenne Fréquences, spécialement étudié pour suivre une balise Ultimate 3 de QRP Labs (http://funkperlen NULL.blogspot NULL.html). La bande de travail ciblée est entre 472 et 479 KHz avec une tension d’alimentation de 13,8V. Il utilise 3 transistors IRFP264 pour un gain de 35dB et un rendement de 65%. Aucun problème pour les modes “continus” comme WSPR même sous 100W.

Mon Grabber QRSS est actif sur 40m

Capture ZL2IK grabber 2014-06-04 80m XV4Y (http://xv4y NULL.radioclub NULL.jpg)Depuis peu, Pete de ZL2IK est actif en transmission QRSS. Il a très souvent décodé et retransmis des capture de mon signal reçu sur 80m, 40m et 30msur son grabber qui est une référence et un des rares à être actif presque 100% du temps depuis ces 5 dernières années (http://zl2ik NULL.html). Je souhaitais lui rendre la pareil. J’ai donc mis en place un grabber sur 40m. Malheureusement j’ai du faire face à une panne du récepteur SDR SoftRock puis du PC lui-même. Finalement depuis quelques jours cela fonctionne et Pete m’aide à affiner les paramètres.

En attendant, si vous souhaitez essayer d’être reçu au Viêt-Nam, vous pouvez vous connecter sur mon grabber et voir si votre signal QRSS arrive jusque le delta du Mékong (http://qsl

Résultats du sondage réalisé par le CQ WW – 2e partie

Sondage CQ WW - Durée d'opération limitée (http://xv4y NULL.radioclub NULL.png)Les organisateurs du concours CQ WW ont publié la suite des résultats de leur enquête sur l’avenir du concours et les améliorations à y apporter (http://cqww

Je vous laisse prendre connaissance directement des graphiques, mais les conclusions importantes sont les suivantes :

  • Une majorité de participants souhaite conserver deux catégories distinctes Single Operator Non-Assisted et Single-Operator Assisted. Seul point notable, c’est que pour les opérateurs européens le résultat est inversé par rapport au reste du monde.
  • Quelque soit la situation (une ou deux catégorie), les personnes sondées disent que cela ne changerait pas leur participation.
  • Une très nette majorité souhaite limiter la durée maximale d’opération durant les 48 heures d’un concours. C’est vrai quelque soit le type d’opération et l’âge. Par contre cette majorité est écrasante pour les européens, peut-être sont-ils défavorisés par rapport aux horaires du concours ou plus liés à des activités familiales.
  • Les participants ne souhaitent pas raccourcir le délai de 5 jours pour remettre un log.
  • 54% des opérateurs pensent qu’il est juste de ne pas compter les QSO avec des indicatifs uniques (uniques pour tout le concours et non pas seulement un OM) car ils sont vraisemblablement issus d’erreurs.
  • Une large majorité souhaite aussi rendre l’envoi de certificat papiers “optionnelle” pour réduire les coûts.

Résultats du sondage réalisé par le CQ WW

CQ WW Sondage Ages (http://xv4y NULL.radioclub NULL.png)Il y a quelques semaines, l’équipe qui organise le CQ WW avec à sa tête Randy K5ZD a lancé un sondage auprès des participants au concours (http://xv4y NULL.radioclub Le but était d’avoir une meilleure connaissance des données démographiques et des motivations des participants. Personnellement j’apprécie cette volonté de vouloir remettre en cause le format de concours existant pour qu’il le mieux possible aux aspirations des contesters actuels et surtout futurs. Attirer de nouveaux membres vers notre hobby doit être une priorité. En tout 5117 réponses ont été reçue ce qui est un échantillon très représentatif à mon avis.

La première partie des résultats tirés de ce sondage est disponible depuis environ une semaine (http://cqww Sans surprise elle dépeint une population plutôt âgée, même si elle est globalement 10 ans plus jeune en Europe qu’aux USA (les deux gros viviers de participants). Plus jeune signifie souvent moins disponible, car pouvoir consacrer 48 heures d’affilées à une activité n’est pas possible pour tous. Par contre à mon grand étonnement les participants européens sont presque deux fois plus nombreux que les américains, mais le concours CQ WW partie télégraphie tombe souvent durant le week-end de Thanksgiving ce qui limite l’assiduité.

CQ WW Sondage Motivations (http://xv4y NULL.radioclub NULL.png)Autres points intéressants, les motivations sont très diverses mais une grande partie des compétiteurs se considèrent comme “sérieux”. De plus, le mode favori reste la CW ce que je comprends car je la trouve plus adaptée tant au DX qu’au concours (automatisation plus facile, meilleure efficacité…). Il serait intéressant d’avoir des informations plus détaillées (motivations pour les jeunes européens par exemple), mais elles ne sont pas disponibles.

Un deuxième article devrait suivre par le comité du CQ WW qui donne des pistes de changement de règles pour réagir par rapport aux résultats du sondage. Il est maintenant disponible (http://xv4y NULL.radioclub

KLog version 9.2.2

KLog EA4TV screenshot (http://xv4y NULL.radioclub NULL.09 NULL.09 NULL.png)Jaime EA4TV m’a récemment informé d’une nouvelle version de KLog, son logiciel de cahier de traffic gratuit qui fonctionne sous OS X, Linux et Windows.

La version 9.2.2 comprend pas mal de corrections de bogues et quelques nouvelles fonctionnalités (http://jaime NULL.robles Elle est disponible en Anglais, Espagnol (Castillan) et Catalan. Jaime est ouvert à d’autres traductions avec votre aide si vous la souhaitez en français.

Mise à jour firmware 2.02 pour les Kenwood TS-590 et TS-590G [MAJ]

Facade TS-590s (http://xv4y NULL.radioclub NULL.jpg)Il y a quelques jours Kenwood a diffusé une mise à jour du logiciel interne de son transceiver TS-590 (l’ancien modèle) (http://www NULL.kenwood NULL.html). Cette version 2.02 ne semble corriger qu’un seul bogue mineur liant changement de Mode et fonction Split que je ne pense pas avoir rencontré. Encore une fois j’apprécie beaucoup que Kenwood prenne le temps de corriger des bogues mêmes mineurs sur un modèle qui n’est plus en production depuis bientôt 2 ans.

Attention, cette mise à jour ne concerne pas le TS-590G qui ne semble pas souffrir du problème.

MAJ : Une nouvelle version du firmware est aussi disponible pour le TS-590G et elle porte le numéro 1.03 (http://www NULL.kenwood NULL.html). Le bogue corrigé est le même.

Des nouvelles positives pour Ten-Tec

Logo Ten-Tec (http://xv4y NULL.radioclub NULL.png)Comme vous le savez certainement, les derniers mois ont été très difficiles pour Ten-Tec qui est passé au bord d’une disparition pure et simple. RKR n’avait pas fait de secrets en interne sur le fait que leur reprise était temporaire et qu’ils souhaitaient revendre Ten-Tec (http://xv4y NULL.radioclub Tout le stock de Ten-Tec avait été soldé dans une démarche de liquidation du stock et de nombreux équipements vendus à pertes alors que les marges étaient déjà mauvaise (on parle de 200$ perdu par transceiver).

Aujourd’hui un nouveau repreneur privé a fait son apparition et K4SWL nous relate une très longue discussion que John Henry KI4JPL a eu sur un forum à propos de l’avenir de l’entreprise et son implication dans le renouveau technique de la gamme (http://qrper Les projets semblent sur le long terme et si les finances le permettent de nouveaux produits verront le jour. L’article en question est plutôt long et je ne peux pas vous en faire une traduction. Reportez-vous au site de et utilisez les traducteurs de Google ou Bing pour en comprendre les grands traits.

Le Raspberry Pi Zero pour seulement 5 USD

Raspberry Pi Zero (http://xv4y NULL.radioclub NULL.jpg)La fondation Raspberry Pi vient d’annoncer le lancement d’une version minimaliste de leur célèbre carte ordinateur embarqué nommée Raspberry Pi Zero. Pour un prix de seulement 5$, ce circuit de la moitié de la taille d’une carte de crédit embarque le même processeur Broadcom BCM2835 que la carte originale mais cadencé à 1 GHz ce qui apporte des performances améliorées de 40%. La mémoire vive est de 512Mo et les entrées-sorties sont réduites avec un port HDMI, deux ports micro-USB et un lecteur de carte micro-SD. Le connecteur “standard” de 40 broches pour les entrées-sorties GPIO est présent, ainsi que des broches permettant une sortie vidéo composite.

Merci à Ars Technica pour l’information (http://arstechnica

Sproutie : La balise QRSS HiFer de Dave AA7EE

AA7EE carte ATTiny programmateur pour Arduino (http://xv4y NULL.radioclub NULL.jpg)Il y a quelques temps, Dave AA7EE m’a contacté pour avoir ma version corrigée du code la balise QRSS de G0UPL/G0XAR (http://xv4y NULL.radioclub Il l’a utilisé pour modifier sa propre balise et la placer sur la bande dite HiFer 13553-13567 KHz  autorisée aux USA sans licence. Lisez sur son blog le détail de son projet. Personellement moi j’adore la construction soignée de son programmateur de micro-contrôleur ATTiny.

Archives des chroniques hertziennes de XV4Y, ZL4YY