Archives par mot-clé : FFT

Spectroscope Audio avec Arduino

[GTranslate]

Si vous souhaitez réaliser ce montage, je propose sur ma boutique en ligne un kit facile à monter contenant tous les composants nécessaires avec la carte micro-contrôleur préprogrammé (http://xv4y NULL.radioclub NULL.asia/boutique/?slug=product_info NULL.php&products_id=29).

Arduino Spectrum Scope FFT XV4Y (http://xv4y NULL.radioclub NULL.asia/wp-content/uploads/2012/10/100_3300 NULL.jpg)Je vous l’avais dit, c’est une petite idée qui me trottait dans la tête depuis quelques temps et j’ai enfin pu la mettre en application. Le montage (ou plutôt le programme car de montage il y en a peu) que vous propose affiche le spectre d’un signal audio de 150 Hz à 3150 Hz en vous donnant le niveau maxi et la bande de fréquence où celui-ci se trouve. Ce n’est pas un analyseur de spectre à proprement dit, puisqu’il utilise la Transformée de Fourier Rapide (http://fr NULL.wikipedia NULL.org/wiki/Transformée_de_Fourier_rapide) à point fixe sur des entiers. En pratique ça fait la même chose…

Le but, c’est de faire joli et d’impressionner les filles d’aider l’opérateur télégraphie à ajuster son VFO pour se caler sur la fréquence de la station reçue (faire le battement nul, quoi).

Pour le réaliser, vous avez besoin :

  1. d’un Arduino avec ATMega168 ou ATMega328,
  2. Arduino Spectrum Scope FFT XV4Yd’un écran LCD 16×2 avec contrôleur Hitachi HD44780 ou compatible
  3. de fils et cavaliers en bon nombre
  4. d’une capacité de 10µF/16V (valeur non critique) avec le point froid (le “-“) sur l’entrée A0 de l’Arduino pour coupler l’audio de votre récepteur au montage
  5. du programme que je mets à disposition ci-dessous que vous allez compiler et télécharger dans l’Arduino

Je vais être franc, je n’ai pas beaucoup écrit de lignes de code pour faire ce programme et je me suis basé sur des librairies existantes. Mon talent (si j’en ai un) est de faire que ça marche! Toutes les références de librairies sont indiquées dans les sources et je vous conseille de vous reporter à leurs documentations respectives.

Arduino Spectrum Scope FFT générateur BF NE555 XV4Y (http://xv4y NULL.radioclub NULL.asia/wp-content/uploads/2012/10/100_3298 NULL.jpg)Les niveaux audio attendus sont entre 0 et 5V (ceux de l’ADC de l’Arduino). Vous pouvez changer l’échelle d’affichage en fonction de ce que vous mettez en entrée. Par exemple, la sortie audio fixe du port ACC du TS-590s donne 1,2V maximum, donc je mettrais le paramètre MAX_AUDIO à 256. Pour mes essais (et les photos), j’ai fait un petit montage générateur BF à base de NE555 (http://electroniccircuitsforbeginners NULL.blogspot NULL.com/2009/12/tone-generator-circuit NULL.html). Celui-ci fourni un beau signal carré plein d’harmoniques qui fait très beau sur l’afficheur!

Ce programme est libre d’utilisation et de modification dans le cadre de la licence GNU GPL v3 (http://www NULL.gnu NULL.org/licenses/gpl NULL.html). Toute inclusion dans un produit commercial ou un kit de composant est sujette à autorisation préalable de l’auteur (moi) et au respect des licences des autres librairies. J’apprécie tous commentaires ou toutes idées d’amélioration!

/*
Arduino HAM Audio Spectrum v1.01
By Yannick DEVOS - XV4Y
http://xv4y.radioclub.asia/

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

====
This program act as an audio Spectrum scope for the low frequency range
It is aimed at help HAM operators to "zero beat" a CW station

You just need to feed some audio (5V peak) into Analog Input 0 of an Arduino board and connect an LCD display.

The display is on a 16x2 LCD Display with HD44780 compatible driver, use the traditional 4 bits interface on pins 12,11,5,4,3,2
It as a graphical display for 20 spectrum bands and also display the numbers for the highest received signal and its band
Frequency is displayed in 20 150 Hz band between 150Hz and 3150Hz

In order to compile this program with Arduino 1.0.1, you will need to install 3 libraries :
- New LiquidCrystal
https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home
- LCDBitmap
http://arduino.cc/playground/Code/LCDBitmap
- Fixed FFT lib for Arduino 1.0
http://code.google.com/p/neuroelec/downloads/detail?name=ffft_library_for_Arduino_1.0.zip&can=2&q=

It is based on various works, please see below.

====
Revision history :
v1.00    2012-10-10
         First release
v1.01    2012-10-11
         Adding the F_STEP parameter and explaining how to change the sample rate    

====
This Example acquire analog signal from A0 of Arduino, and Serial out to Processing application to visualize.
Tested with preamplified audio data. Take a look at http://www.youtube.com/watch?v=drYWullBWcI

Analog signal is captured at 9.6 KHz, 64 spectrum bands each 150Hz which can be change from adcInit()
Load the this file to Arduio, run Processing application.

Original Fixed point FFT library is from ELM Chan, http://elm-chan.org/works/akilcd/report_e.html
A way to port it to the Arduino library and most demo codes are from AMurchick http://arduino.cc/forum/index.php/topic,37751.0.html
Processing app is based on codes from boolscott http://boolscott.wordpress.com/2010/02/04/arduino-processing-analogue-bar-graph-2/

====
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 <stdint.h>
#include <ffft.h>
#include <Wire.h>
#include <LiquidCrystal.h>
#include <LCDBitmap.h>

// Here a few things that yoy may want to change

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);  // You can change this settings to your convenance, please see the library documentation

LCDBitmap bitmap(&lcd, 0, 0);

#define  IR_AUDIO  0    // ADC channel to capture
#define  F_STEP    150  // Width of the frequency bands in Hertz. This constant is only for display. To actually change the
                        // the size of the bands you have to change the FFT_N constant in ffft.h.
                        // 64 gives 300Hz (6300Hz displayed), 128 gives 150Hz (3150Hz displayed), 256 gives 75Hz.
                        // More samples means slower execution. Values higher than 256 do not seem to work. SRAM exhaustion ?
#define  MAX_AUDIO 512  // The maximum audio level you're expecting (for scaling), 5V is 1023
#define  OFFSET    1    // Spectrum band offset for display, first band has a lot of 50Hz hum so we skip it
#define  REFR_RATE 10   // Rate for refreshing the numerical display

// There are no user settings that you can modify here below

volatile  byte  position = 0;
volatile  long  zero = 0;
volatile  int   val, j, max_i, max_val, refresh;

byte graph[20];

int16_t capture[FFT_N];			/* Wave captureing buffer */
complex_t bfly_buff[FFT_N];		/* FFT buffer */
uint16_t spektrum[FFT_N/2];		/* Spectrum output buffer */

void setup() {
  lcd.begin(16,2);
  lcd.home ();

  adcInit();
  adcCalb();

  lcd.clear();
  bitmap.begin();
}

void loop() {
   if (position == FFT_N) {
     fft_input(capture, bfly_buff);
     fft_execute(bfly_buff);
     fft_output(bfly_buff, spektrum);

     max_val = max_i = 0;

     for (byte i = 0; i < 21; i++) {                 // We are capturing more (64 bands) than we can actually display (only 20)...
        j = i+OFFSET;
        val = map(spektrum[j],0,MAX_AUDIO,0,16);   // Scaling for display, only 16 dots high
        graph[i] = val;
        if (spektrum[j]>max_val) {          // Save the higher values for further display it
          max_val = spektrum[j];            // The value
          max_i = j;                        // Its band
        }
     }

    // Here we draw the graph
    bitmap.barGraph(20, graph, ON, UPDATE);

    // Here we display the highest numerical value but not each cycle because it flickers
    refresh++;
    if (refresh == REFR_RATE) {
      lcd.setCursor ( 4, 0 );
      lcd.print("Max F:    ");
      lcd.setCursor ( 10, 0 );
      lcd.print((max_i+1)*F_STEP);
      lcd.setCursor ( 14, 0 );
      lcd.print("Hz");
      lcd.setCursor ( 4, 1 );        // go to the next line
      lcd.print("Value:    ");
      lcd.setCursor ( 10, 1 );
      lcd.print(max_val*5);
      lcd.setCursor ( 14, 1 );
      lcd.print("mV");
      refresh = 0;
    }
    position = 0;
  }
}

// free running ADC fills capture buffer
ISR(ADC_vect) {
  if (position >= FFT_N)
    return;

  capture[position] = ADC + zero;
  if (capture[position] == -1 || capture[position] == 1)
    capture[position] = 0;

  position++;
}

void adcInit() {
  /*  REFS0 : VCC use as a ref, IR_AUDIO : channel selection, ADEN : ADC Enable, ADSC : ADC Start, ADATE : ADC Auto Trigger Enable, ADIE : ADC Interrupt Enable,  ADPS : ADC Prescaler  */
  // free running ADC mode, f = ( 16MHz / prescaler ) / 13 cycles per conversion 
  ADMUX = _BV(REFS0) | IR_AUDIO; // | _BV(ADLAR); 
//  ADCSRA = _BV(ADSC) | _BV(ADEN) | _BV(ADATE) | _BV(ADIE) | _BV(ADPS2) | _BV(ADPS1) //prescaler 64 : 19231 Hz - 300Hz per 64 divisions
  ADCSRA = _BV(ADSC) | _BV(ADEN) | _BV(ADATE) | _BV(ADIE) | _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0); // prescaler 128 : 9615 Hz - 150 Hz per 64 divisions, better for most music
  sei();
}

void adcCalb() {
  lcd.setCursor ( 0, 0 );        // go to the next line
  lcd.print("FFFT Spectrum");
  lcd.setCursor ( 0, 1 );        // go to the next line
  lcd.print("Calibration");
  long midl = 0;
  // get 2 meashurment at 2 sec
  // on ADC input must be NO SIGNAL!!!
  for (byte i = 0; i < 2; i++) {
    position = 0;
    delay(200);
    midl += capture[0];
    delay(200);
  }
  zero = -midl/2;
}

Futurs projets pour micro-contrôleurs

Ecran LCD 16x2 (http://xv4y NULL.radioclub NULL.asia/wp-content/uploads/2012/09/LCD16_2 NULL.jpg)Ce n’est pas pour tout de suite mais je commence à me gratter la tête pour de nouveaux projets autour de mon Arduino (vais-je en acheter un deuxième ?) ou de mon LaunchPad.

Je viens de recevoir un écran LCD 16×2 commandé à très bon prix sur eBay (http://www NULL.ebay NULL.com/itm/1pcs-1602-16x2-HD44780-Character-LCD-Display-Module-LCM-blue-blacklight-New-/251155458075?pt=LH_DefaultDomain_0&hash=item3a7a08281b). Le vendeur basé à Hong Kong s’étant montré très bien, je lui ai commandé un capteur de température et d’humidité (http://www NULL.ebay NULL.com/itm/1pcs-DHT11-Digital-Humidity-Temperature-Sensor-/251056594544?pt=LH_DefaultDomain_0&hash=item3a74239e70), un ensemble émetteur-récepteur 433 MHz (http://www NULL.ebay NULL.com/itm/1pcs-433Mhz-RF-transmitter-and-receiver-kit-Arduino-project-/261041100836?pt=LH_DefaultDomain_0&hash=item3cc7431824) et un convertisseur port USB vers signaux RS232/TTL (http://www NULL.ebay NULL.com/itm/1pcs-PL2303-USB-RS232-TTL-Converter-Adapter-Module-/251082091781?pt=LH_DefaultDomain_0&hash=item3a75a8ad05). Avec les trois premiers, j’aimerai bien essayer de monter un petit capteur météo à distance autour d’un ATTiny8 par exemple. Un Arduino ferait la collecte des résultats et l’affichage sur le LCD. Ensuite le micro-ordinateur viendrait récupérer des points de mesure une fois par jour pour faire des stats… Le convertisseur pour port USB c’est au passage, histoire de pouvoir faire tourner des micro-contrôleurs de manière indépendante.

L’écran LCD me servirait aussi pour un autre projet, celui de faire un analyseur de spectre Audio (par FFT) pour brancher sur le transceiver. Rien de révolutionnaire mais avoir un affichage centré autour de 600 Hz pourrait être une aide intéressante pour se caler sur le bon signal en CW. Je n’ai pas une très bonne oreille et parfois dans le feu de l’action en entendant un indicatif rare je ne me cale pas bien. Je n’ai jamais perdu de QSO à cause de cela mais ce n’est pas très poli pour l’autre opérateur… Plusieurs projets construits autour d’un Arduino existent sur ce sujet dont celui-ci qui me plaît bien (http://lusorobotica NULL.com/index NULL.php?topic=2985 NULL.0).

Video analyseur de spectre audio Arduino (http://www NULL.youtube NULL.com/watch?v=Zpz8XP4go3U)

Ici un autre mais je comprends moins bien le polonais que le portugais (http://www NULL.youtube NULL.com/watch?v=Bn6BIfr_UgY)