Étiquette : MSP430

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

Prototype kit Balise WSPR DDS XV4Y (http://xv4y NULL.radioclub NULL.asia/wp-content/uploads/2012/12/100_3339 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 NULL.asia/docs/). 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
    http://xv4y.radioclub.asia/

    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
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You can download a copy of the GNU General Public License at <http://www.gnu.org/licenses/>
*/

// Here modify to your taste or needs

#define PTT_key          P2_2
#define ANALOG_BUTTONS   A5
#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);

  myDDS.begin();
  
   
  pinMode(ANALOG_BUTTONS, INPUT);

  myScreen.begin();
  myScreen.setBacklight(1);
    
  myScreen.setFont(1);
  myScreen.text(0, 0, "sVFO");
  myScreen.text(0, 2, "AD9850");
  myScreen.setFont(0);
  myScreen.text(0, 4, "v1.00 - XV4Y");
  myScreen.text(0, 5, "Init...");
  
  delay(1000);
  
  myDDS.reset();
  
  myDDS.SetFrequency( frequency_A, 0, false );

  digitalWrite( PTT_key, LOW );

};

//******************************************************************
// Here starts the actual sequence sending

void loop() {
    myScreen.clear();
    myScreen.setBacklight(1);
    myScreen.setFont(1);
    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 );
    };

    myScreen.setFont(0);
    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
        break;
#endif

      } 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
        break;
#endif

      } 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"
            freq_select++;
            if (freq_select > 14) freq_select = 0;
            if (vfo == 1) frequency_B = frequencies[freq_select]; else frequency_A=frequencies[freq_select];
            multiplier--;
            break;
          };
        };
        multiplier++;
        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;
            multiplier++;
            break;
          };
        };
        multiplier--;
        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;
          };
        };
        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;
        break;
      };
    }

};


//******************************************************************
// 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;
  }
}

Nouvelle version de l’IDE Energia qui supporte nouveaux LaunchPad

Texas Instruments LaunchPad Tiva C port Ethernet (http://43oh NULL.com/2014/03/energia-ve0012-release-adds-iot-and-fram-launchpad-support/)Une nouvelle version de l’IDE Energia, portage de l’environnement de développement Arduino pour les plateformes Texas Instruments, vient d’être annoncée. Cette release 0101E0012 apporte le support de deux cartes supplémentaires ainsi que la correction de nombreux bogues (http://energia NULL.nu/download/). Ces cartes Texas Instruments sont :

  • La nouvelle LaunchPad Tiva C (http://www NULL.ti NULL.com/ww/en/launchpad/launchpads-tivac-ek-tm4c1294xl NULL.html)EK-TM4C1294XL (http://www NULL.ti NULL.com/tool/ek-tm4c1294xl) avec processeur Cortex-M4 à 120Mhz, 1 Mo de Flash, 256Ko de SRAM et surtout un port Ethernet 10/100 pour moins de 20$!
  • La LaunchPad MSP-EXP430FR5969LP (http://www NULL.ti NULL.com/ww/en/launchpad/launchpads-msp430-msp-bndl-fr5969lcd NULL.html) avec 64Ko de FRAM qui est disponible dans un bundle avec un BoosterPack écran LCD pour moins de 30$.

Autre nouveauté très importante sur Energia, le support des DriverLib API de Texas Instruments qui apporte de nombreuses facilité de programmation pour les LaunchPad à MSP430 et Tiva C.

Ma pomme dans CQ Magazine de Décembre – Kits balise WSPR

Sommaire CQ Décembre 2013 (http://xv4y NULL.radioclub NULL.asia/wp-content/uploads/2013/11/2013_12_cq_toc NULL.jpg)Le numéro “Spéciale technique” de décembre de CQ Magazine (http://www NULL.cq-amateur-radio NULL.com/) contiendra un article que j’ai écrit à propos des micro-contrôleurs MSP430 et du LaunchPad de Texas Instruments. En fait j’ai proposé cet article il y a plus d’un an mais ils ne trouvaient pas la place adéquate dans leurs colonnes.

Pour continuer sur ma lancée, je leur ai aussi proposé un article détaillant comment fabriquer sa propre balise WSPR ou QRSS avec un DDS AD9850 et un LaunchPad MSP430. C’est en fait la balise que je proposais en kit (http://xv4y NULL.radioclub NULL.asia/2013/03/21/la-balise-wspr-de-g4jvf/) dont je vais publier les schémas et code source. En principe l’article est accepté pour une publication au premier semestre 2014, j’attends leurs demandes de corrections.

Il y a quelques jours Hans G0UPL a lancé son kit Ultimate QRSS beacon 3 (U3) (http://hanssummers NULL.com/ultimate3 NULL.html)qui a maintenant atteint un bon niveau de fonctionnalité et surtout de stabilité (les premières versions ont essuyées pas mal de bogues). Il propose en option les kits module GPS et platine de filtre de bande à commutation par relais. C’est aujourd’hui l’offre la plus intéressante car il en produit des volumes de plusieurs centaines d’exemplaires. Son seul inconvénient c’est que Hans refuse d’en ouvrir le code source et qu’il est donc impossible de faire vos propres adaptations…

Au passage je suis content de voir que mon travail a porté ses fruits et que Hans a intégré dans son codes des idées issues du mien comme la mise en veille du DDS par le bit W34 et le mode WSPR-15 (pour les VLF). Je suis sûr que le côté “reprogrammable” de mes kits l’a aussi poussé à diffuser les binaires de ses firmwares en ligne pour que les utilisateurs puissent faire les mises à jour, ce qu’il ne voulait pas faire au début.

Un wobuloscope à partir d’un Raspberry Pi et d’un DDS

MI0IOU Wobuloscope Raspberry Pi (http://xv4y NULL.radioclub NULL.asia/wp-content/uploads/2013/10/MI0IOU_wobby1 NULL.jpg)Aujourd’hui, les “vrais techniciens” ne jurent que par l’analyseur de spectre ou l’analyseur de réseau vectoriel (VNA). Ces équipements sont devenus relativement bon marché et des versions “simplifiées” du dernier sont même à la portée de toutes les bourses radioamateurs ou presque. Toutefois, il fut un temps où ces équipements étaient rares et où le Wobuloscope était l’équipement de choix pour les amateurs. Largement suffisant pour caractériser un filtre ou un circuit oscillant, j’ai mis les mains sur un appareil vintage lorsque je préparais ma licence au radio-club RCNEG de F6KKU (merci à F6GUB et F9ZS(SK) au passage).

Tom de MI0IOU a conçu un équipement équivalent mais en le remettant à la mode grâce au Raspberry Pi et aux modules DDS AD9850 d’origine chinoise (http://asliceofraspberrypi NULL.blogspot NULL.co NULL.uk/2013/10/raspberry-pi-wobbulator-introduction NULL.html). Le RPi pilote le DDS et en fait varier la fréquence, et il effectue la lecture d’un signal “redressé” par un circuit de détection simple. Le RPi n’ayant pas d’entrée analogique, un module convertisseur analogique-numérique (ADC) est nécessaire. La couverture est uniquement pour les bandes HF, mais c’est suffisant pour la plupart d’entre nous. Des exemples de mesures sont disponibles sur le blog de MI0IOU (http://asliceofraspberrypi NULL.blogspot NULL.co NULL.uk/2013/10/using-raspberry-pi-wobbulator-to-test_28 NULL.html). Tom met aussi à disposition le code Python à installer sur le Raspberry Pi.

Je vais vous avouer que j’avais commencé à travailler sur un circuit similaire en utilisant un LaunchPad MSP430. L’idée était de reprendre mon code de contrôle de l’AD9850 (http://xv4y NULL.radioclub NULL.asia/2013/03/19/code-source-vfo-avec-dds-ad9850ad9851-et-launchpad-msp430/) et de faire la lecture avec le port ADC du micro-contrôleur. L’affichage était en texte sur l’écran d’un micro-ordinateur connecté au MSP430 part le port USB. Faute de temps libre pour ce type de projet, celui-ci est passé en voie de garage tout comme celui de kit station météo complète (http://xv4y NULL.radioclub NULL.asia/2013/02/04/station-meteo-avec-serveur-web-code-source/) avec modules sans-fil et pression atmosphérique.

Contrôler un Si570 avec le LaunchPad MSP430 par F4DTR

Intérieur Si570 - Photo http://hifiduino.wordpress.com/2012/10/17/inside-the-silicon-labs-si570-programmable-xo/ (http://xv4y NULL.radioclub NULL.asia/wp-content/uploads/2013/09/Inside_Si570 NULL.jpg)Vous allez le voir, aujourd’hui, c’est un peu la journée du MSP430 avec 3 billets sur le sujet…

Tout d’abord, Jean-Yves de F4DTR a partagé sur le forum de 43oh.com son travail autour du Si570 (http://forum NULL.43oh NULL.com/topic/4380-change-frequency-to-si570-dxo-on-i2c-not-fully-fonctionnal/). C’est un travail en cours et malheureusement il manque de temps pour le faire aboutir. Si vous êtes à l’aise avec l’écriture de code pour le MSP430 sur Energia et que vous souhaitez bénéficier d’un oscillateur agile, stable et de très large gamme couverte, alors donnez-lui un coup de main.

Montage d’un Amplificateur 5W classe C de chez kitsandparts.com

Ampli 5W Classe C kitsandparts.com terminé (http://xv4y NULL.radioclub NULL.asia/wp-content/uploads/2013/06/100_3568 NULL.jpg)

Ampli 5W Classe C kitsandparts.com terminé

Cela fait presque 9 mois que ce kit commandé chez Kits & Parts (http://kitsandparts NULL.com/qrp_amp2 NULL.php) traînait dans un tiroir de mon bureau. Je l’avais trouvé comme étant le compagnon parfait et plutôt économique pour mes kits balises QRSS et WSPR (http://xv4y NULL.radioclub NULL.asia/boutique/). Les commentaires sur internet sont très positifs. Plusieurs de mes clients l’avaient monté avec succès (http://xv4y NULL.radioclub NULL.asia/2013/03/21/la-balise-wspr-de-g4jvf/) mais étant pris par différentes activités et par la vente de kits eux-même, je n’avais pas eu le temps de me pencher sur ce circuit.

Ce week-end après une semaine chargée je voulais me détendre, et ce kit comprenant assez peu de pièces et étant en principe d’une difficulté technique faible (pas de réglages, pas de CMS…) je pensais pouvoir le faire en quelques heures. Première leçon que j’avais oublié : ne jamais se dire qu’on va faire quelque chose en vitesse. En gros tout est allé de travers ou presque. Tout d’abord j’ai utilisé comme générateur de signal en entrée un kit balise avec AD9851 que je m’étais mis de côté pour essayer de comprendre ce qui clochait avec ces modules DDS (les modules AD9850 sont parfaits, les AD9851 plus chers et catastrophiques, je ne les vends plus). Sur ce kit j’avais modifié le circuit d’alim pour tester différentes tension d’alimentation du AD9851, et quand j’ai voulu faire mes tests la carte LaunchPad s’est retrouvée avec du 12V… Il va sans dire que ni le MSP430 ni les circuits du port USB du LaunchPad n’ont apprécié. J’ai donc testé un nouveau mode de transmission : les signaux de fumée. S’en est suivi une réparation du circuit et l’ajout d’un régulateur 5V, mais là encore j’ai pris en hâte un 78L05 en me disant que le DDS ne consommait (de mémoire) que 80mA. Ce qui est vrai à 3,3V, mais pas à 5V où il consomme 110mA, le 78L05 se mettait donc à sortir 5V pendant 10 secondes puis 2,2V pendant 10 autres secondes… et moi je ne comprenais pas pourquoi mon signal disparaissait. Encore du temps perdu alors que si j’avais vérifié dans la datasheet dès le début j’aurais mis un TLV1117-5 directement ce qui était en plus un meilleur choix.

Composants de l'Ampli 5W Classe C kitsandparts.com (http://xv4y NULL.radioclub NULL.asia/wp-content/uploads/2013/06/100_3566 NULL.jpg)

Composants de l’Ampli 5W Classe C kitsandparts.com

Pour revenir au kit par lui-même, il m’a aussi posé des soucis. La documentation, bien que contenant toutes les informations nécessaires, n’est pas des plus claires concernant le bobinage du transformateur T2. Pour une raison qui m’est inconnue l’auteur du kit rend cette étape plus compliquée qu’elle ne devrait l’être à mon goût. Je me suis donc retrouvé avec un circuit qui ne marchait pas du premier coup.

Ajoutez à cela le fait que le PCB (très propre au demeurant) utilise des diamètres de pastille très petites, qui ne facilitent pas la soudure et le changement d’un composant, et vous avez compris mes difficultés. De plus sur certaines pastilles l’étain ne voulait pas adhérer et j’ai eu quelques soudures sèches. Le fil de cuivre pour bobiner les inductances et de bonne qualité avec une triple couche de vernis. Cela veut aussi dire que quand on doit gratter le vernis pour souder il reste parfois quelques résidus qui viennent vous enquiquiner lors du montage.

Signal 14 MHz sortie ampli 5W kitsandparts.com (http://xv4y NULL.radioclub NULL.asia/wp-content/uploads/2013/06/100_3570 NULL.jpg)

Signal 14 MHz sortie ampli 5W kitsandparts.com, 10V crête

Mon temps pour me pencher sur les raisons du dysfonctionnement était limité car les enfants sont à la maison le week-end et nous nous ne sommes pas totalement dégagés de charge professionnelle pour autant. Il faut dire aussi que de travailler tranches de 15 minutes n’aide pas à éviter les erreurs…  Bon, j’ai donc rebobiné le transformateur T2 (il y avait suffisamment de fil de cuivre en rab), trouvé des points alternatifs pour les soudures qui ne pouvaient plus se faire sur les pastilles d’origine (par chances, des masses) et réglés tout les petits problèmes un par un. Là tout est rentré dans l’ordre et j’ai eu un beau signal de 1W en sortie sur 14 MHz pour 2,5mW en entrée (oui, le filtre sur les modules AD9851 est poussif). Quand je dis beau, je dis conforme à ce que j’attendais d’un amplificateur de classe C. Il va de soit que ce signal demande filtrage pour être transmis sur l’air. Je précise qu’en entrée le DDS me fournit une superbe sinusoïde.

Signal 3,5 MHz sortie ampli 5W kitsandparts.com (http://xv4y NULL.radioclub NULL.asia/wp-content/uploads/2013/06/100_3572 NULL.jpg)

Signal 3,5 MHz sortie ampli 5W kitsandparts.com

Mon objectif premier avec ce kit était de faire une balise WSPR pour le 80 mètres. Cela me permettrait de connaître facilement les périodes favorables au DX sur cette bande. L’hiver je passe beaucoup de temps à appeler un peu dans le vide, et optimiser mon temps de traffic en connaissant à l’avance les meilleurs ouvertures serait très profitable. Quand j’ai placé le DDS sur 3,5 MHz ce que j’ai vu sur l’oscilloscope m’a fait peur! Je savais qu’une classe C sortait un signal distordu, mais je ne pensais pas trouver une forme d’onde si complexe et riche en harmoniques. Heureusement j’avais commandé le kit filtre passe-bas pour la bande des 80 mètres (http://kitsandparts NULL.com/univlpfilter NULL.php). Ce filtre a été monté peu après la rédaction de cet article (http://xv4y NULL.radioclub NULL.asia/2013/06/23/montage-dun-kit-filtre-passe-bas-universal-de-kits-and-parts/).

Les résultats de transmission de ma balise WSPR sont excellents avec 12 700 km pour 1W sur 80 mètres (http://xv4y NULL.radioclub NULL.asia/2013/07/08/wspr-et-propagation-estivale-sur-la-bande-des-80-metres/). Je vais donc conclure sur ce kit et vous donner mon avis.

  • Oui je recommande l’achat de ce kit. Le prix est imbattable pour le service rendu. La qualité du design et des composants est indéniable.
  • Tout le matériel nécessaire est fourni, mais rien de plus. C’est à vous de trouver les connecteurs et d’avoir un stock de composants et tous les outils nécessaires.
  • Non, ce n’est pas un kit pour débutant. D’une part il ne fait rien par lui-même. D’autre part, la documentation est un peu “sèche”. Personnellement je trouve qu’il lui manque un petit côté pédagogique et une explication sur les choix des composants (pourquoi une diode PIN MP3700 sur le circuit de gain ?). Quand on achète un kit c’est qu’en général on ne se sent pas capable de concevoir le circuit soi-même depuis le début, et qu’on cherche à se faire la main pour apprendre.
  • Les PCB avec de petites pastilles sont de plus en plus courant et je trouve ça dommage. Nous sommes en général tous un peu des bricoleurs et aimons à modifier le circuit après coup pour comprendre son fonctionnement et peut-être l’améliorer. Avec les petites pastilles, dessouder un composant devient difficile, et dessouder un transformateur HF sans abimer le circuit est impossible.

 

Le Stellaris LaunchPad rebaptisé Tiva C

Texas Instruments Tiva C LaunchPad (http://xv4y NULL.radioclub NULL.asia/wp-content/uploads/2013/04/2013-04-12_Tiva_Launchpad_angle NULL.jpg)Texas Instruments a apporté quelques modifications à sa plateforme hardware pour micro-contrôleurs haute performance. En plus d’être renommée Tiva C LaunchPad, le composant soudé sur la carte est un TM4C123GH6PM qui ajoute des capacités de PWM, QEI, Hôte USB avec OTG. Cette dernière fonctionnalité USB On-The-Go est un peu ce qui manquait à la précédente version et permet de connecter beaucoup plus facilement un clavier ou un autre périphérique de saisie et surtout d’accéder aux mémoires de masse sur port USB (disque dur, Flash…). Le prix est toujours de 13 USD ce qui le rend très très attractif face aux 10 USD auxquels est passé le LaunchPad MSP430 de TI.

Code source VFO avec DDS AD9850/AD9851 et LaunchPad MSP430

sVFO DDS AD9850 MSP430 XV4Y (http://xv4y NULL.radioclub NULL.asia/wp-content/uploads/2013/03/100_3446 NULL.jpg)J’ai eu le temps de mettre la main à une première version d’un programme simple de VFO pour mon kit à base de DDS AD9850 ou AD9851 (http://xv4y NULL.radioclub NULL.asia/boutique/?slug=product_info NULL.php&products_id=33).

Cette première mouture reste assez simple avec juste un système VFO A et VFO B mais pas de mémoires. Les fonctionnalités des boutons suivent la description ci-dessous.

 

Pour une pression brève sur le bouton :

  • UP : Augmente la valeur du chiffre sélectionné (pour le VFO sélectionné)
  • DOWN : Diminue la valeur du chiffre sélectionné (pour le VFO sélectionné)
  • LEFT : Sélectionne le chiffre de rang supérieur (plus à gauche)
  • RIGHT : Sélectionne le chiffre de rang inférieur (plus à droite)
  • OK : Valide la fréquence et la transmet au DDS

Pour une pression longue (supérieure à 1 seconde) sur le bouton :

  • LEFT : Positionne la fréquence sur la limite basse de la bande suivante
  • RIGHT : Egalise les fréquences des deux VFO (VFO A = VFO B)
  • OK : Change le VFO sélectionné (VFO A/B)

A noté que la broche P2_2 du MSP430 (celle connectée à la broche 3 du connecteur 4 pins) est maintenant utilisée en entrée. Si son état change (passant à 0V par exemple), le VFO actuellement utilisé est momentanément interverti. Cela permet donc de trafiquer en split avec la fréquence transmise par le DDS qui change du VFO A vers VFO B (ou l’inverse) tant que la PTT est pressée.

/* Simple VFO with DDS for MSP430G2553
 * Code for Energia 009

 * By Yannick DEVOS - XV4Y - March 2013
    http://xv4y.radioclub.asia/

    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
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You can download a copy of the GNU General Public License at <http://www.gnu.org/licenses/>
*/

// Here modify to your taste or needs

#define PTT_key          P2_2
#define ANALOG_BUTTONS   A5
//#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
// Encoding the WSPR sequence

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

  myDDS.begin();

  pinMode(ANALOG_BUTTONS, INPUT);

  myScreen.begin();
  myScreen.setBacklight(1);

  myScreen.setFont(1);
  myScreen.text(0, 0, "sVFO");
  myScreen.text(0, 2, "AD9850");
  myScreen.setFont(0);
  myScreen.text(0, 4, "v1.00 - XV4Y");
  myScreen.text(0, 5, "Init...");

  delay(1000);

  myDDS.reset();

  myDDS.SetFrequency( frequency_A, 0, false );

  digitalWrite( PTT_key, LOW );

};

//******************************************************************
// Here starts the actual sequence sending

void loop() {
    myScreen.clear();
    myScreen.setBacklight(1);
    myScreen.setFont(1);
    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 );
    };

    myScreen.setFont(0);
    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
        break;
#endif

      } 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
        break;
#endif

      } 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"
            freq_select++;
            if (freq_select > 14) freq_select = 0;
            if (vfo == 1) frequency_B = frequencies[freq_select]; else frequency_A=frequencies[freq_select];
            multiplier--;
            break;
          };
        };
        multiplier++;
        if (multiplier > 8) multiplier = 8;

      } 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;
            multiplier++;
            break;
          };
        };
        multiplier--;
        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;
          };
        };
        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;
        break;
      };
    }

};

//******************************************************************
// 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;
  }
}

Station météo avec serveur web – code source

Prototype station météo (http://xv4y NULL.radioclub NULL.asia/wp-content/uploads/2013/02/100_3440 NULL.jpg)J’ai continué mes travaux autour de ma mini-station météo avec serveur web. J’ai atteint les objectifs de fonctionnalités que je m’étais fixés, même s’il me reste à enrichir de quelques indicateurs les statistiques. Ensuite il me faudra repasser toutes les valeurs en type float car je les avais mises en entier pour gagner de la place mémoire et parce que l’espace d’affichage sur l’écran LCD était limité. Il me faudra aussi faire un peu de gestion de la cohérence des valeurs pour éviter d’afficher 255°C quand mon capteur distant n’a plus de piles (comme actuellement). A propos du capteur distant, il faudra aussi que je travaille sur son code pour gérer la mise en veille afin d’économiser les batteries. Dernier point important, j’attends toujours mes capteurs de pression atmosphérique (ils sont assez chers donc j’ai hésité à les inclure dans les kits) pour pouvoir gérer ce type de mesures. L’architecture générale étant présente ça ne devrait pas prendre trop de temps à mettre en place.

Vous pouvez donc le voir par vous-même sur ce prototype de mini serveur web météo (http://cairang NULL.radioclub NULL.asia:8080/), cela fonctionne et plutôt bien à mon goût. Ne vous étonnez pas si parfois il y a peu de valeurs affichées car je continue à faire des tests et à remettre à zéro les mémoires…

J’ai même eu ma première commande, car XYL a trouvé cela pratique (pour une fois à propos de mes montages) et en aura besoin d’un pour son café-restaurant. Les services de l’hygiène demande de relever ces valeurs chaque jour en principe, même si dans la réalité peu de monde le fait… Comme elle ne prévoit pas d’ouvrir le service de restauration avant avril, j’ai le temps de mettre tout cela au point.

Je dois encore faire une étude précise, mais je pense pouvoir proposer ces stations météos autour de 70$, le prix variant suivant les options (écran, contrôleur Ethernet, capteur de pression…). Dès que je peux, je mets les informations à jour sur la page produit de la boutique (http://xv4y NULL.radioclub NULL.asia/boutique/?slug=product_info NULL.php&products_id=31). Les composants sont en fait assez chers si on veut une précision correcte (les capteurs DHT-11 par exemple ne sont bons que pour des mesures relatives) et il y a deux micro-contrôleurs (un pour la station et un pour le capteur distant). Dans tous les cas ça ne sera pas avant mi-mars prochain car les approvisionnements vont être bloqués pour plusieurs semaines à partir du week-end prochain avec le nouvel an lunaire.

En attendant je partage avec vous le code source du premier programme de test que j’avais fait pour mon prototype de mini station météo web (http://xv4y NULL.radioclub NULL.asia/2013/02/01/mini-station-meteo-web/). Il a évolué depuis mais celui-ci en principe fonctionne et offre le service de base… Il est prévu pour un Arduino Nano (ATMega328) et se compile avec Arduino 1.0.1. Je vous conseille d’utiliser mes packages librairies (http://xv4y NULL.radioclub NULL.asia/boutique/docs/) pour pouvoir les compiler.

/*
Arduino Thermometer and Humidity mini web server using internal and remote DHT11 sensors
By Yannick DEVOS - XV4Y
http://xv4y.radioclub.asia/

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

====
This program sense and displays the current temperature and relative humidity for a local and remote sensors
It serve the values to a mini web server thanks to an ENC28J60 Ethernet module

In order to compile this program with Arduino 1.0.1, you will need to install 3 libraries :
- DHT-sensor Library by Adafruit
https://github.com/adafruit/DHT-sensor-library
- VirtualWire Library by Mike McCauley
http://www.open.com.au/mikem/arduino/VirtualWire.pdf
- Ethercard Library by JeeLabs
http://jeelabs.net/pub/docs/ethercard/index.html
====
Revision history :
v1.00    2013-02-02
         First release with mini web server test
====
This program needs at least 2KB of SRAM, that means an ATMega328...

The DHT11 Sensor need to be connected as described here below
- Connect pin 1 (on the left) of the sensor to +5V
- Connect pin 2 of the sensor to whatever your DHTPIN is (here pin D12)
- Connect pin 4 (on the right) of the sensor to GROUND
- Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor
We also need a push button on pin D2.

For RF modules, please see the VirtualWire documentation

====
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
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You can download a copy of the GNU General Public License at <http://www.gnu.org/licenses/>
*/

#include <EtherCard.h>
#include "DHT.h"
#include <VirtualWire.h>

// Here some parameters you would like to edit

#define RXPIN  A1        // What pin we use for Remote Sensor RX module
#define BAUDRATE 2000    // Transmission speed in bps, 1000-2000 is ok a give similar ranges, higher is useless
#define RX_LOST 60       // Max time in seconds without the sensor is considered lost
#define DHTPIN A2        // What pin we have connected the DHT sensor
#define DHTTYPE DHT22

// ethernet interface ip address
static byte myip[] = { 192,168,1,100 };
// gateway ip address
static byte gwip[] = { 192,168,1,254 };

// ethernet mac address - must be unique on your network
static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };

const byte header[4] = {0x01,'D','H','T'};

// Here you should not be touching it

const char http_OK[] PROGMEM =
    "HTTP/1.0 200 OK\r\n"
    "Content-Type: text/html\r\n"
    "Pragma: no-cache\r\n\r\n";

const char http_Found[] PROGMEM =
    "HTTP/1.0 302 Found\r\n"
    "Location: /\r\n\r\n";

const char http_Unauthorized[] PROGMEM =
    "HTTP/1.0 401 Unauthorized\r\n"
    "Content-Type: text/html\r\n\r\n"
    "<h1>401 Unauthorized</h1>";

DHT dht(DHTPIN, DHTTYPE);

byte Ethernet::buffer[700]; // tcp/ip send and receive buffer
BufferFiller bfill;

int hi=0xFF, ti=0xFF, hr=0xFF, tr=0xFF;
int last_rx;
unsigned int counter=0;

float tf=1;

byte buf[VW_MAX_MESSAGE_LEN];
byte buflen = VW_MAX_MESSAGE_LEN;

void setup(){
  ether.begin(sizeof Ethernet::buffer, mymac);  // Start the Ethernet module
  ether.staticSetup(myip, gwip);

  vw_set_rx_pin(RXPIN);
  vw_setup(BAUDRATE);

  vw_rx_start();       // Start the RF receiver PLL running
}

void loop() {

  hi = int(dht.readHumidity());    // we convert to integer since the DHT11 has not enough precision anyway
  ti = int(dht.readTemperature());

  if (vw_have_message()) {  // If we have a message from the RF module
    if (vw_get_message(buf, &buflen) && !memcmp(&buf, &header,4)) // If it is checked and the header is the same
    {
      // First temp, the RF module send a float but we only display an integer
      memcpy(&tf, &buf[4], 4);
      tr = int(tf);

      // THen humidity
      memcpy(&tf, &buf[8], 4);
      hr = int(tf);

      last_rx = millis()/1000;  // We save when was the last data received
    }
  }

  if ((millis()/1000) > (last_rx+RX_LOST)) {    // Without signal from the sensor for more than RX_LOST seconds, the sensor is considered out of reach
    hr = 0xFF;
    tr = 0xFF;
  }  

  // wait for an incoming TCP packet, but ignore its contents
  word len = ether.packetReceive();
  word pos = ether.packetLoop(len); 
  if (pos) {
    delay(1);
       bfill = ether.tcpOffset();
       char *data = (char *) Ethernet::buffer + pos;
    if (strncmp("GET /", data, 5) != 0) {
       // Unsupported HTTP request
       // 304 or 501 response would be more appropriate
       bfill.emit_p(http_Unauthorized);
    } else {
       data += 5;

       if (data[0] == ' ') {
           // Return home page
           homePage();
           counter++;
       } else {
           // Page not found
           bfill.emit_p(http_Unauthorized);
       }
    }
        ether.httpServerReply(bfill.position());    // send http response
  }
}

void homePage()
{
    bfill.emit_p(PSTR("$F"
        "<meta http-equiv='refresh' content='5'/>"
        "<title>Mini web météo v1.0 XV4Y</title>" 
        "<h1>Le temps du delta du mékong chez <a href=\"http://xv4y.radioclub.asia\">XV4Y</a></h1>"
        "<h2>Capteur interne</h2>"
        "Temp : $D°C</br>"
        "Hum. : $D%</br>"
        "<h2>Capteur distant</h2>"
        "Temp : $D°C</br>"
        "Hum. : $D%"
        "<h6>$Dème connexion.</h6>"
        "<h5>Copyright(C)2013 - <a href=\"http://xv4y.radioclub.asia/\">Yannick DEVOS XV4Y</a></h5>"
        ),
        http_OK,
        ti,
        hi,
        tr,
        hr,
        counter);
}

Voici aussi le code pour le capteur distant. Il fonctionne lui sur un MSP430G2452 et est écrit avec Energia 009.

/* Remote Temperature/Humidity sensor for MSP430G2452
 * Code for Energia 009

 * By Yannick DEVOS - XV4Y - December 2012
    http://xv4y.radioclub.asia/

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

====
  * Run on MSP430G2452
  * Hook a DHT sensor module to pin P2_1
  * Hook a 433MHz TX module to P2_4
  * Several pins are available for LED debugging
====
Revision history :
v1.00    2012-12-18
         First release, without MCU power saving features

====
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
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You can download a copy of the GNU General Public License at <http://www.gnu.org/licenses/>
*/

#include "DHT.h"
#include <VirtualWire.h>

#define DHTTYPE DHT11
#define DHTPIN   P2_1     // DATA Pin pour le DHT
#define TXPIN    P2_4     // DATA Pin pour le module TX RF
#define BAUDRATE 2000     // Transmission speed in bps, 1000-2000 is ok a give similar ranges, higher is useless
#define PWRPIN   P1_6     // Pin to turn ON/OFF power to the modules
#define LEDERR   P1_0     // This LED will turn on when DHT is not ok

float h, t;
byte trame[12] = {0x01,'D','H','T',0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};  // The frame to be transmitted with "DHT" as header

DHT dht(DHTPIN, DHTTYPE);

void setup() {
  pinMode(PWRPIN, OUTPUT);     
  pinMode(LEDERR, OUTPUT);     

  vw_set_tx_pin(TXPIN);
  vw_setup(BAUDRATE);

  dht.begin();
}

void loop() {
  digitalWrite(PWRPIN, HIGH);  // Apply power to the modules
  delay (1000);                // We have to wait 1 second to let the DHT sensor stabilize

  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  t = dht.readTemperature();
  h = dht.readHumidity();

  // Check if returns are valid, if they are both 0 then something went wrong!
  if (t == 0 && h == 0) {
    digitalWrite(LEDERR, HIGH);
  } else {
    // First temperature
    memcpy(&trame[4], &t, 4);
    // Then humidity
    memcpy(&trame[8], &h, 4);
    vw_send((byte *)trame, 12);
    digitalWrite(LEDERR, LOW);
  }
  vw_wait_tx(); // Wait until the whole message is gone

  digitalWrite(PWRPIN, LOW);  // We turn off power to save batteries
  delay(5000);                // We rest 5 seconds before the next reading, longer wait time will save more batteries...

}

 

Librairie VirtualWire 1.12 pour le MSP430 [MAJ2]

[GTranslate]

Pour une fois, je ne cache pas ma fierté. En environ 2 heures de travail, j’ai réussi mon premier vrai portage d’une libairie conçue pour l’Arduino, la librairie VirtualWire (http://www NULL.open NULL.com NULL.au/mikem/arduino/), vers le MSP430 avec Energia. Sans être un exploit, c’est un succès personnel car cela demande de se plonger dans le travail des autres, ce qui n’est jamais facile.

La difficulté technique était, je l’avoue, faible, car la seule spécificité matérielle était liée aux Timer de l’AVR qui sont différents du MSP430. Par contre, une certaine dose de réécriture de code a été nécessaire pour que cela se compile convenablement car il y a toute de même quelques différences entre les deux environnements Arduino et Energia dès qu’on commence à écrire en C.

Pour mémoire, le but de cette librairie et de pouvoir utiliser des petits modules de communication sans-fil sur 433 MHz ou 2,4 GHz pour relier deux micro-contrôleurs. Ces modules étant souvent très sommaires au niveau matériel avec une transmission du signal bande de base en On-Off Keying (tout ou rien), il faut que le logiciel apporte quelques subtilités supplémentaires pour rendre la transmission fiable. On peut ensuite obtenir des débits de 9000 bps ou plus souvent environ 2000 bps si on s’éloigne de 150 mètres. C’est suffisant pour faire un capteur de station météo (http://xv4y NULL.radioclub NULL.asia/boutique/?slug=product_info NULL.php&products_id=31) par exemple…

Le code n’est pas complètement testé mais compile correctement et les premiers essais que j’ai pu faire s’avèrent très concluants. J’ai entre autres fait communiquer un Arduino et un MSP430 par liaison sans-fil ce qui prouve que les timings sont stables!

Je mets à disposition le code source tel qu’il est aujourd’hui avec peut-être encore des bugs. N’hésitez pas à me faire parvenir vos commentaires pour l’améliorer! La documentation d’origine (http://www NULL.open NULL.com NULL.au/mikem/arduino/VirtualWire NULL.pdf) reste valable pour cette version du code.

MAJ :   (http://xv4y NULL.radioclub NULL.asia/ftp/VirtualWire_110_EnergiaMSP430_20120109 NULL.zip)L’auteur a intégré mes modifications et publié une nouvelle version de la librairie, la 1.12, qui devrait fonctionner à la fois sur Arduino et Energia. Elle est téléchargeable ici (http://www NULL.open NULL.com NULL.au/mikem/arduino/VirtualWire/).

MAJ2 :   (http://xv4y NULL.radioclub NULL.asia/ftp/VirtualWire_110_EnergiaMSP430_20120109 NULL.zip)Il semblerait que l’auteur de la librairie originale a bien intégré mes apports mais n’a pas testé la librairie et celle-ci ne fonctionne pas. Voici mon portage de VirtualWire 1.10 pour Energia/MSP430 tel que je l’utilise (http://xv4y NULL.radioclub NULL.asia/ftp/VirtualWire110_Energia_XV4Y NULL.zip).