[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).
(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 :
- d’un Arduino avec ATMega168 ou ATMega328,
- d’un écran LCD 16×2 avec contrôleur Hitachi HD44780 ou compatible
- de fils et cavaliers en bon nombre
- 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
- 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.
(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; }
good job man ,,,, is there any video displaying the work ,,,
thank u
Hi,
Unfortunately no video and no time right now to record one…
Yan.
ok can i ask u some questions about the project ?
Of course, go ahead.
ok ,,
just i want to know what actually the project do
does it find the frequency of the sound and the amplitude ? or what ?
(max_i+1)*F_STEP : is this contains the value of sound frequency for the instant signal ?
max_val*5 : the amplitude of sound signal in mV
if i want to modify the code to activate an arduino Pin for every frequency rang ? can i do this ?
and can i change the ranges by make them wider ?
thanx a lot
Hi,
Sorry for taking that long to answer but I have been busy on other projects.
The firmware does not really measure a frequency. After doing a FFT, he looks for which bin has the highest value.
Knowing the bin width and its “position” we can then determine the “frequency band” where is located the highest signal. If the bin is narrow, this is close to a frequency measurement (but not exact).
You can make the bin wider by altering the parameters in the FFT library, then, F_STEP must reflect the value you calculated in order to “guess” the frequency.
Regards,
Yannick.