Emetteur AM avec relayage FM
Principe du montage
Les stations de radio qui émettent en AM deviennent de plus en plus rare, il deviendra bientôt impossible d'utiliser nos vieilles radio à lampes d'un autre temps faute d'avoir quoique ce soit à recevoir.
En GO, il nous reste RTL, la BBC et Alger, c'est terminé par contre pour France Inter, Europe1 et RMC. Même chose en PO avec l'arrêt des émetteurs de FIP, France-Info et radio-bleue.
J'ai donc décidé de construire un émetteur AM
(ce n'est pas le premier) mais celui-ci sera particulier, car il relayera les stations FM vers leurs fréquences initiales qu'elles avaient en AM. Grosso-modo, avec une préselection je pourrai par exemple décider de retransmettre les émissions de france-inter recues en FM (87.8 Mhz à Paris) vers la fréquence utilisée autrefois en AM (162 Khz).
Pour chaque préselection, les paramètres règlables seront la fréquence du tuner, la fréquence d'émission, l'accord de l'antenne, le volume du tuner. Nous disposerons d'une interface avec un encodeur muni d'un interrupteur et un afficheur LCD. La réception FM est confié à un module SI4703, la génération de porteuse se fera via un AD9833. Pour l'accord de l'antenne, je ne sais pas si je ferais une commutation de capa avec des petits relais ou bien un CV piloté par un moteur pas à pas. La gestion de l'ensemble sera confié à un arduino nano.
Ce qui nous donne ce schéma de principe.
Pour Paris, une liste de préselection de ce genre pourrait être définie comme point de départ
Liste des composants nécessaires
Pour la partie moderne du montage vous devrez vous munir des composants suivants :
Un arduino nano. Parce que c'est pratique, ca prend peut de place et ca coute pas cher, surtout les versions "chinese" :) et en plus les broches sont face à face au pas de 2.54 ce qui n'est pas le cas du Uno.
Un module de réception FM basé sur la puce SI4703. C'est un récepteur FM stéréo RDS pilotable en I2C.
Un module pour générer la porteuse AM basé sur la puce AD9833. C'est un module permettant de construire un générateur de fonction à peut de frais. Le générateur est de type DDS et il peut monter à 12.5Mhz
Et pour l'interface homme-machine, un écran LCD de 20x4 pilotable lui aussi en I2C
(donc sur le même bus que le tuner FM)
Et un encodeur rotatif muni d'un interrupteur.
Pour la partie ancienne, un certain nombre de composants que je n'ai pas encore défini, je n'ai pas encore construit cette partie...
Première utilisation
Etant donné que les données des préselections sont sauvegardées dans l'EEPROM, il faut formater celle-ci lors de la première utilisation. La séquence pour le formatage est la suivante :
- mettre hors tension le montage
- appuyer sur le switch de l'encodeur
- maintenir la touche appuyée pendant que l'on remet sous-tension
- rester toujours appuyé pendant encore 2 secondes environ
Une fois le message d'accueil passé, le formatage à lieu
Utilisation et IHM
Un seul encodeur
(avec interrupteur) est utilisé pour régler l'appareil. J'ai volontairement
simplifié au maximum les commandes. Pour autant, avec ce seul bouton, nous pouvons effectuer les
tâches suivantes :
- sélection d'un preset
- fréquence du tuner
- volume du tuner
- fréquence de l'emetteur
- réglage bobinage de sortie
- mémorisation d'un preset
Voici ce que vous verrez à l'écran.
- La ligne du haut définie la fréquence de réception (91.8 Mhz ici), et à sa droite le nom de station recu par RDS. Quand le nom de station n'est pas encore décodé (réception mauvaise par exemple, ou bien si l'emetteur ne gère pas le RDS) <No RDS> sera affiché.
- puis en dessous la fréquence de porteuse de l'émetteur. Ici nous avons 150khz.
- Ensuite, l'accord d'antenne. Je ne sais pas l'unité que j'utiliserai mais surement la valeur en capa du CV à la sortie. Mettons que ca sera entre 10 et 500pf...
- en dessous le volume audio du tuner. cela impactera la profondeur de modulation. Le réglage est celui du SI4703 soit entre 1 et 15.
- En bas à droite, entre crochet, nous avons le numero de préselection en court.
L'utilisation est simple. De base on tourne l'encodeur à droite ou à gauche pour choisir une préselection.
Pour entrer en mode programmation, on choisit d'abord une préselection à modifier et on appuye sur l'encodeur. Les flèches entourent la fréquence de réception.
On choisit la fréquence de réception avec l'encodeur en tournant à droite ou à gauche. On appuye pour valider, les flèches entourent maintenant la fréquence de l'émetteur.
On règle maintenant la fréquence de l'emetteur et on valide ensuite en appuyant sur le bouton. les fèches se déplacent vers la sélection du bobinage d'antenne.
Ici les 2 bobinages en série
La petite astérisque devant la fréquence d'émission indique le règlage fin de la fréquence par pas de 1khz. On sélectionne le réglage fin en restant appuyé 1 seconde sur le bouton de l'encodeur. On rebascule sur un intervale de 10Khz en rappuyant 1 seconde.
Ici uniquement le bobinage GO (LW),
(le bobinage PO est court-circuité par un relais.)
Ici uniquement le bobinage PO (MW),
(le bobinage GO est court-circuité par l'autre relais.)
On choisit donc le bobinage approprié. On valide en appuyant. Les flèches se déplacent sur le volume de réception.
Pour finir, il nous reste donc à règler le niveau audio de la réception (et indirectement la profondeur de modulation). On valide une dernière fois.
Lors de la dernière validation, la préselection est sauvegardée.
Lecture de l'encodeur
L'encodeur utilisé importe peu, c'est du tout-venant provenant d'un site chinois quelconque, le tout est qu'il soit muni d'un interrupteur qui permette de valider les réglages.
Il n'y a pas de bibliothèque particulière à utiliser pour cet encodeur dans mon programme. Par
contre, j'utilise un timer
(le timer 1) avec une fréquence de 2ms pour aller voir la dernière
position de l'encodeur et mettre à jour une variable en mémoire. Je pourrai ensuite lire quand je
veux cette variable et connaitre le sens dans lequel l'encodeur a été manoeuvré.
Initialisation du timer
void init_encoders(void) {
// Pin initialization for encoders
//------------------------------------------
for(int i=0;i<NB_ENCODEURS;i++) {
pinMode(pinA[i], INPUT); // define pin A inputs
pinMode(pinB[i], INPUT); // define pin B inputs
digitalWrite(pinA[i],HIGH); // Pull-up ON for pins A
digitalWrite(pinB[i],HIGH); // Pull-up ON for pins B
}
pinMode(PIN_ENCODER_SW, INPUT); // define encoder switch pin
digitalWrite(PIN_ENCODER_SW,HIGH); // Pull-up ON for switch pin
TIMSK1 &= ~(1<<TOIE1); // Timer/Counter1, Overflow Interrupt Disable
TCCR1A &= ~((1<<WGM11) | (1<<WGM10)); // timer/counter mode normal
TCCR1B &= ~(1<<WGM12); //
TIMSK1 &= ~(1<<OCIE1A); // Output Compare A Match Interrupt Disable
TCCR1B |= (1<<CS10) | (1<<CS11) ; // CLKio/64 (from prescaler)
TCCR1B &= ~(1<<CS12);
tcnt1 = 65037; // init temp counter for 2ms
TCNT1 = tcnt1; // init real counter timer 1
TIMSK1 |= (1<<TOIE1); // Timer/Counter1, Overflow Interrupt Enable
}
Interruption du timer sur overflow
Lorsque le timer passe en overflow
(donc au bout de 2ms, puisqu'on l'a réglé en conséquence...) une interruption est généré et le code contenu dans
ISR(TIMER1_OVF_vect) sera exécuté.
IMPORTANT : Suivant la résolution des pas de l'encodeur vous serez peut-être amené à modifier la dernière ligne qui contient bcounter[i]=counter[i]>>1; et remplacer celle-ci par bcounter[i]=counter[i]>>2; Cette ligne défini une division du nombre de pas. Entre chaque cran de l'encodeur, celui-ci peut envoyer une séquence d'avance de 2 pas ou 4 pas, il faut donc diviser en conséquence pour que le compteur s'incrémente normalement.
ISR(TIMER1_OVF_vect) {
int MSB;
int LSB;
int encoded;
int sum;
byte i;
TCNT1 = tcnt1; // Reload du timer
for (i=0;i<NB_ENCODEURS;i++) {
//MSB = digitalRead(pinA[i]); // MSB = most significant bit
//LSB = digitalRead(pinB[i]); // LSB = least significant bit
MSB = bitRead(PIND,pinA[i]); // MSB = most significant bit
LSB = bitRead(PIND,pinB[i]); // LSB = least significant bit
encoded = (MSB <<1) |LSB; // conversion
// A 4 bits sum variable is build
// the 2 most significant bits are the last read
// the 2 last significant bits are the current read
sum = (lastEncoded[i] << 2) | encoded; // Build 4 bits sum
// Test if we turn CW
if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011)
counter[i]++;
// Test if we turn CCW
if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000)
counter[i]--;
lastEncoded[i] = encoded; // Store current state for next time
// Depend on encoder type used
// sometime you need to divide by 2 and sometime divide by 4
// bcounter[i]=counter[i]>>2; // Counter divided by 4
bcounter[i]=counter[i]>>1; // Counter divided by 2
}
}
Lire la position des encodeurs
On utilise ici la fonction
readEncodeurs()Cette fonction n'aura qu'un encodeurs à observer mais cette routine peut être utilisée pour lire plusieurs encodeurs en même temps, NB_ENCODEURS définie le nombre d'encodeurs à lire. La fonction est utilisable pour 9 encodeurs et renvoie des valeurs de 1 à 9 si un des encodeurs est tourné à gauche, elle renvoie des valeurs de 11 à 19 si un des encodeurs est tourné à droite. Le tableau lcounter
(dernières positions connue des encodeurs) est comparé au tableau bcounter
(positions courantes des encodeurs).
//--------------------------------------------
// Routine principale de lecture des encodeurs
//--------------------------------------------
byte readEncodeurs(void) {
byte i,val;
val=0;
// Lire les encodeurs
for (i=0;i<NB_ENCODEURS;i++) {
// si la valeur a variee pour un des encodeurs
if (lcounter[i]!=bcounter[i]) {
// Tester le send
// Si UP valeur de 11 a 14
if (bcounter[i]>lcounter[i])
val=i+11;
// Si down valeur de 1 a 4
else
val=i+1;
lcounter[i]=bcounter[i];
return val;
}
}
return 0;
}
Lecture de la position du switch
On utilise la fonction
readButtons() pour lire la position du switche
La fonction readButtons renvoie 0 si le switch n'est pas appuyé. Elle renvoie B_ENC1 si le switch vient juste d'être appuyé depuis la dernière lecture et renvoie B_MAINT si le switch est resté appuyé depuis la lecture précédente (c'est à dire que nous avions déja B_ENC1 lors de la lecture précédente. Cette bidouille est utilisée pour connaitre si on reste appuyé sur un bouton plus que 2 cycles de lecture. Je me sers de ce système pour le formatage de l'EEPROM entre autre.)
byte readButtons() {
int c = 0;
if (!bitRead(PIND,PIN_ENCODER_SW)) {
if (lastBoutonNav) { // if the button was already pressed
lastBoutonNav=B_MAINT; // then this is a long press
return B_MAINT;
}
// else we have to debounce
// we wait for 10 ms for this
delay(10);
if (!bitRead(PIND,PIN_ENCODER_SW)) { // if the bit is still 1
lastBoutonNav=B_ENC1; // we are sure that the button is 'really' pressed
return B_ENC1;
}
}
lastBoutonNav=0;
return 0;
}
Ecran LCD
L'écran LCD est un afficheur LCD standard, utilisable en I2C de 20 car sur 4 lignes. J'utilise la bibliothèque
LiquidCrystal_I2C pour le faire fonctionner. Le mien a l'adresse 0x27.
L'arduino est un arduino nano 5V, j'ai pris un afficheur LCD qui sera utilisable directement sur cette tension.
Le LCD dispose d'un module I2C soudé directement dans son dos.
Les pins SDA et SCL du LCD, sont respectivement connectées aux pins A4 et A5 de l'arduino comme n'importe quel composant O2C.
L'arduino utilisé est un modèle 5V, donc les pins A4 et A5 sont portées elles aussi au potentiel de 5V pendant les dialogues sur le bus. Si vous ajoutés d'autres composants I2C sur ce montage vérifiez si vos modules le supporte, certains ne tournent qu'en 3.3V. Ici par exemple, le LCD est fait pour être utilisé en 5V. Le tuner, est aussi branché sur ce bus I2C et pourtant son alimentation propre est en 3.3V. Cela peut fonctionner parce qu'il possède un pont diviseur sur ses entrées SAD et SCL et il est donc protégé. Lisez bien vos datasheets avant de rajouter des composants additionnels sur ce bus.
Récepteur FM SI4703
Ce petit module est très complet. C'est un véritable tuner FM stéréo RDS avec un petit amplificateur capable de faire fonctionner un casque avec un volume tout à fait respectable. Le seul petit défaut pour ce module gros comme un timbre poste est le fait que la masse (enfin plutot le fil commun aux deux canaux) sert d'antenne. A l'origine, le chip utilisé est fait pour etre intégré dans des téléphones portables pour leur rajouter un tuner. Nous verrons comment faire une petite modification plus loin puisqu'il faudra bien brancher une antenne et donc séparer l'audio de l'antenne.
Pour le reste ce module permet la réception de la bande FM de 88.0 à 108.0mhz pour l'europe mais peut aussi utiliser un étalement différent pour d'autre pays.
L'espacement entre les stations est de 100khz pour l'Europe, cela peut aussi etre modifié pour d'autres pays.
Il est compatible RDS et peut recevoir toutes les subtilités de ce standard (nom de la station, ID de la station, information routieres, genre de musique de la station, radiotext, etc... La liste est longue tant le standard RDS est complet). En ce qui nous concerne la seule partie RDS dont nous nous servirons est le nom de la station.
Il existe un certains nombre de bibliothèque disponible et je ne vais pas réinventer la roue. Je me suis donc fortement inspirée de la librairie fournie par sparkfun qui vend aussi ce type de module. Mais... j'ai fait quelques modifications parce qu'il y avait certains bugs. Notamment, la fonction pour lire le nom des stations ou les messages radiotext. Régulièrement elles ne fonctionnaient pas. de plus elles étaient bloquantes, ce qui fait que nous étions bloqués tant que le nom de la station n'était pas lu et encore pire lors de la lecture d'un radiotext.
Il ne faut pas oublié que le RDS est assez lent et que le décodage dépend fortement de la qualité de réception. De plus les messages ou les noms de stations sont envoyés par morceaux et ceux la peuvent forcément arriver dans le désordre puisque de temps en temps, si les conditions sont mauvaises, il manquera des morceaux.
Le raccordement à l'arduino est assez simple. Comme le module se pilote en I2C il faudra déja le raccorder sur le même bus que le LCD, sur les pins A4 et A5 de l'arduino. Une autre pin est nécessaire, il s'agit de la pin RESET qui sera relié à la pin 2 de l'arduino. Cette pin permet de resetter le module SI4703 mais aussi de le mettre dans le mode I2C au démarrage.
Comme vu plus haut, ce module est alimenté en 3.3V, faites bien attention pour le brancher à la sortie 3.3V de l'arduino ou sur un régulateur 3.3V séparé si vous préférez.
Au démarrage il faut expliquer au module qu'il sera utilisé sur un bus I2C. Pour cela, il y a une petite astuce. Il faut mettre la pin SDIO à l'état bas, et faire la meme chose sur la pin RESET. On attend 1ms, puis on repasse la pin RESET à l'état haut et on attend de nouveau 1ms. Arrivé à ce stade, le module est mis en mode I2C. Il suffit ensuite d'utiliser la bibliothèque wire pour parler avec.
pinMode(RESET_PIN, OUTPUT);
pinMode(SDIO_PIN, OUTPUT); // SDIO is connected to A4 for I2C
digitalWrite(SDIO_PIN, LOW); // A low SDIO indicates a 2-wire interface
digitalWrite(RESET_PIN, LOW); // Put Si4703 into reset
delay(1); // Some delays while we allow pins to settle
digitalWrite(RESET_PIN, HIGH); // Bring Si4703 out of reset with SDIO set to low and SEN pulled high with on-board resistor
delay(1); // Allow Si4703 to come out of reset
Wire.begin(); // Init I2C
Ensuite, la communication s'établit avec le SI4703 par l'intermédiaire de registres comme c'est le cas pour la plupart de ce genre de composant (ca sera la même chose avec le module AD9833 nous verrons cela plus loin), donc, comme c'est souvent le cas, une fonction permet l'écriture dans les registres pour donner des ordres à l'équipement, c'est la base. Mais nous aurons aussi une autre fonction qui permettra de lire dans les registres et récupérer du contenu (comme le fait de connaitre le canal en cours, si la stations peut diffuser ou pas de l'information routieres, pour lire les messages RDS par exemple mais aussi le niveau de réception...)
la fonction pour lire dans les registres se nomme
si4703_readRegisters() et la fonction pour écrire
si4703_updateRegisters()
Les registres sont maintenu en mémoire dans un tableau nommé si4703_registers[] Ce tableau nous sert d'intermédiaire avant d'écrire dans le SI4703, on écrit d'abord dans le tableau et on lance la procédure de mise à jour. Même chose dans l'autre sens, on demande à lire les registres, le tableau se mets à jour et on lit dans ce tableau. Ce tableau est en quelque sorte une copie des registres du SI4703.
Et... Bien entendu... Il y a des particularités. Il y a 16 registres, numeroté de 0x00, à 0x0F, chaque registre fait 16 bits donc 2 octets, nous aurons donc au total 32 octets à lire. Jusque la, ca va. Mais... le SI4703 ne renvoie pas les 16 registres dans l'ordre quand on lui demande de renvoyer 32 octets. Il renvoie d'abord les registres de 0x0A à 0x0F puis ensuite ceux de 0x00 à Ox09. Un détail bon à savoir.
On utilise les fonctions Wire standard pour communiquer.
Wire.requestform() pour demander les 32 octets, et tant que
Wire.available() est vrai on lit les données avec
Wire.read()
void si4703_readRegisters(void){
//Si4703 begins reading from register upper register of 0x0A and reads to 0x0F, then loops to 0x00.
Wire.requestFrom(SI4703, 32); //We want to read the entire register set from 0x0A to 0x09 = 32 bytes.
while(Wire.available() < 32) ; //Wait for 16 words/32 bytes to come back from slave I2C device
//We may want some time-out error here
//Remember, register 0x0A comes in first so we have to shuffle the array around a bit
for(int x = 0x0A ; ; x++) { //Read in these 32 bytes
if(x == 0x10)
x = 0; //Loop back to zero
si4703_registers[x] = Wire.read() << 8;
si4703_registers[x] |= Wire.read();
if(x == 0x09)
break; //We're done!
}
}
//-----------------------------------------------------
// Write the current 6 control registers (0x02 to 0x07)
// don't need to specify an address. The IC assume you
// are starting with 0x02 first...
//-----------------------------------------------------
byte si4703_updateRegisters(void) {
Wire.beginTransmission(SI4703);
for(int regSpot = 0x02 ; regSpot < 0x08 ; regSpot++) {
byte high_byte = si4703_registers[regSpot] >> 8;
byte low_byte = si4703_registers[regSpot] & 0x00FF;
Wire.write(high_byte); //Upper 8 bits
Wire.write(low_byte); //Lower 8 bits
}
//End this transmission
byte ack = Wire.endTransmission();
if(ack != 0) { //We have a problem!
// Serial.print("Write Fail:"); //No ACK!
// Serial.println(ack, DEC); //I2C error: 0 = success, 1 = data too long, 2 = rx NACK on address, 3 = rx NACK on data, 4 = other error
return(FAIL);
}
return(SUCCESS);
}
Générateur HF AD9833
Pour générer la porteuse HF nous allons utiliser un circuit AD9833.
Ce circuit permet de générer une forme d'onde sinus, triangle ou carrée de 0 Mhz à 12.5Mhz. Le circuit ne nécesite pas d'horloge, tout est intégré. Il se branche sur le bus SPI de l'arduino et nécessite une alimentation en +5V.
Malgré l'apparente complexité du circuit (d'après le datasheet) le circuit est relativement simple à programmer. Comme pour le SI4703, il se programme via un registre de 16 bits dont voici le contenu.
La fonction
ad9833_init() permet d'initialiser le bus SPI.
void ad9833_init(void) {
// SG_Reset();
// SG_freqReset(calcFreq(freqSGLo), waveType);
cli();
DDRB |= 0x2E; // Out for SCK,MOSI, pin 10, ping 9
SPCR = 0x58; // SPI init : SPE, MASTER, CPOL (SPI_MODE2)
SPSR = 0x01; // SPIX2 active
PORTB |= (1<<1); // CS pin 9
sei(); // Autorisation interruption
}
La fonction
write_AD9833() permet d'écrire dans le registre 16 bits du circuit AD9833
void write_AD9833(int AD_Register) {
PORTB &= ~(1<<1); // Chip select pin 9
SPDR = highByte(AD_Register); // Copie MSB + 4 bits programmation du DAC
// (buffered, 1x gain et active mode)
while (!(SPSR & (1<<SPIF))); // Attente de la copie
SPDR = lowByte(AD_Register); // Copie du LSB
while (!(SPSR & (1<<SPIF))); // Attente de la copie
PORTB |= (1<<1); // Chip un-select pin 9
}
La fonction la plus intéressante est celle qui permet de sélectionner la génération d'une fréquence en sinus. Il s'agit de la fonction
SG_frequencySet(long frequency, int wave). Cette fonction prend 2 paramètres, la fréquence en hertz et la sélection de forme d'onde
(sinus dans le cadre de notre utilisation)
void SG_frequencySet(long frequency, int wave) {
long fl = frequency * (0x10000000 / 25000000.0); // calc frequency for AD9833
// reset (b:9)
// LSB+MSB write consecutively (b:13)
write_AD9833(0x2100);
// write lower part of frequency. only the 14 first bits, mask with 3FFF (b0:13)
// or with 0x4000 to force bit 14 to 1 (FREQ0 write)
write_AD9833((int)(fl & 0x3FFF) | 0x4000);
// write upper part of frequency.
// shift 14 bits right (b0:13)
// or with 0x4000 to force bit 14 to 1 (FREQ0 write)
write_AD9833((int)((fl & 0xFFFC000) >> 14) | 0x4000);
// Setup for phase write
write_AD9833(0xC000);
// Send control register for wave form select
// if 0x0000, means sinus, freq0, phase0, onboard DAC, internal clock
write_AD9833(wave);
}
L'envoi des données se compose de plusieurs étapes.
- calcul de la fréquence
- reset du chips et préparation de l'envoi (b:9 et b:13)
- ecriture des 14 bits les plus significatifs de la fréquence
- shift de 14 bits à droite,écriture du reste avec b:14 forcé à 1
- mode phase write
- selection de la forme d'onde. 0x0000 par défaut sélectionne forme d'onde sinus, freq0 et phase0, utilisation du DAC interne et horloge interne
Les presets
Comme vu plus haut la sélection des 16 presets se fait en tournant le bouton de l'encodeur.
Pour modifier un preset on effectue un appui long sur le bouton de l'encodeur et on entre en mode programmation. Par l'intermédiaire de rotation et de l'appui sur le bouton de l'encodeur, on sélectionne chaque paramètre et on en modifie la valeur. Une fois la dernière étape validée
(le réglage de volume en l'occurence) le preset édité est sauvegardé automatiquement.
La sauvegarde s'effectue dans l'EEPROM de l'arduino, ce qui ne nécessite pas l'ajout d'une puce mémoire c'est bien pratique.
Je n'utilise rien de particulier pour accéder à l'EEPROM si ce n'est les fonctions natives de l'environnement qui sont
EEPROM.read et
EEPROM.write().
Maintenant que nous avons vu la partie électronique moderne, accédons à la partie électronique "à l'ancienne".
Le schéma
Voici le schéma que j'ai mis en pratique.
Je ne l'ai pas représentée ici mais l'alimentation est confiée à un transformateur avec 2 secondaires simples de 6.3V/2A et 200V/0.085A. Le redressement se faire avec un pont de diodes composée de 4 diodes 1N4007, toutes shuntés avec un condensateur de 10nF/630V. Vient ensuite un premier filtrage de 47µF puis 500 ohms de chutrice
(2 résistances de 1K/10W en parallèles) et enfin un second filtrage de 47µF. Ce qui va nous donner environ de 200 à 240V continus en charge
(tout dépend du réglage écran de la lampe HF)
Nous avons ici 3 lampes.
- 6V6 : amplification BF pour piloté écran de la modulatrice
- 6V6 : modulatrice. recoit la BF sur son écran et la HF sur sa grille. La plaque est réliée sur le circuit d'antenne
- EF89 : préamplificatrice HF. Permet de remonter un peu le niveau de HF du generateur qui plafonne à 0.6V maximum. Cet étage n'est pas trop forcé il a un gain en tension de 8 environ
La sortie du générateur HF est reliée à la grille de la EF89 via un condensateur de 470pf. La polarisation de cette lampe est automatique (165 ohms dans la cathode) et nous avons 33K sur l'écran. La plaque est reliée à la grille de la modulatrice 6V6 via un condensateur de 220pF.
La modulatrice 6V6 à une polarisation automatique avec 150 ohms dans la cathode, avec 10µF en parallèle. L'écran recoit d'une part la tension continue disponible sur la plaque de la BF via 330K.
Sur mon montage perso, j'ai mis une commutation de résistance sur plusieurs valeurs échelonnées de 33K à 800K environ.
La partie audio du signal est envoyée aussi sur l'écran via un condensateur de 100nF, ce qui permet de faire varier la tension d'écran en fonction de l'amplitude du signal audio. La tension d'écran variant, le gain de la lampe HF va varier lui aussi en fonction du signal BF ce qui permet bien d'avoir une modulation d'amplitude. Cette méthode de modulation n'est pas la plus performante et la plus élégante mais elle peut se monter à peu de frais et évite par exemple l'emploi de gros transformateur de modulation, compliqués à trouver et de toutes facons très chers.
L'accord d'antenne se fait via 2CV de postes classique, de la pure récupération. Et entre les 2 CV nous avons notre bobinage antenne, composée de 2 selfs fabriquées maison avec des pots en ferrite. Le fil utilisé pour le obinage GO est du fil émaillé de 0.2mm mélangé avec un fil en coton et je bobine les 2 en même temps.
Nous avons 2600µH pour le bobinage GO et 204µH pour le bobinage PO.
Les 2 bobinages sont en série et les contacts des 2 relais permettent de court-circuiter une bobinage ou l'autre, ou aucune. Ce qui permet de les avoir en série, ou bien l'une ou l'autre indépendamment. Un réseau de transistor ULN2003 assure l'interface avec l'arduino et la commande des relais.
Les cables marrons à gauche et à droite sont soudés directement sur les CV.
La partie BF est assez simple. Le tuner est branché sur un petit transfo de type LT-44 qui me permet d'avoir un gain de 4 ou 5 environ, ce qui permet d'attaquer la grille de la 6V6 directement sans préampli BF aditionnel. Sur le schéma sont représentés 2 transfos, mais un seul est suffisant et branché sur un seul des canaux de sortie du tuner
(Le signal est forcé en mono par logiciel).
Pour la charge, j'utilise une self de 30 HY de 60mA achetée chez tube-town. Mais un transformateur de sortie dont on utilisera que le primaire peut faire l'affaire. Nous avons 68K sur l'écran de la 6V6 BF, elle est loin d'être poussée dans ces derniers retranchement. La liaison avec l'écran se fait avec une résistance de 330K (ou une commutation de résistances comme expliqué plus haut) et la partie BF est véhiculée par un condensateur de 100nF.
Les selfs de 2.2mH dans les plaques des EF89 et 6V6 ont été bricolées à partir de tube de bakelite.
Modification du SI4703
Il est nécessaire de modifier la petite plaquette de réception FM. En effet, initialement ce circuit est fait pour être utilisé avec un casque et la masse du casque (du moins le point commun au 2 écouteurs) sert aussi de fil d'antenne. Ici, le circuit sera cablé au plus près du transformateur de liaison, ce qui ne constituera pas une antenne correcte. Il faut donc modifier un peu le circuit en coupant deux pistes, ajouter un strap et aménager une sortie antenne
Vous allez mieux comprendre avec le schéma d'origine :
Initialement, la prise U2 est la prise casque. La patte connecté a l'anneau extérieur qui est commun au 2 écouteurs, est au potentiel de la masse via la self pour que la BF soit bien véhiculée et elle doit être connectée aussi à la broche 2 du chip principal du tuner, via un condo de 1nF, pour acheminer la HF (la partie antenne du tuner...)
2 solutions s'offre a vous.
- Isoler les 2 composants self et condensateur en coupant 2 pistes. Connecter la prise casque vers la self et une antenne sur le condensateur
- Ou bien carrément dessouder le condensateurs CMS et en souder un autre avec une patte en l'air connecté vers l'antenne
J'ai pris la première option. J'ai coupé 2 pistes, et soudé un fil depuis le condensateur vers un connecteur de fortune collé sur la plaquette. Et j'ai fait un strap pour relier le 'ring' de la prise casque vers l'ampli.
Ci-dessous un lien qui pointent sur un fichier pdf qui contient non seulement le schéma de la platine SI4703 mais aussi les modifications à apporter.
SI4703 schema et modifications
Montage des éléments
Pour la tolerie nous avons ceci. Une boite en alum de récupération d'un vieux montage
Le chassis
Une face avant
On fixe le chassis sur la face avant avec 4 vis.
On perce les trous pour le potard, les 2 CV, le galva, le LCD, encodeurs, interrupteurs, etc...
Sous le chassis on fixe des barettes à cosses pour souder les composants. J'ai mis aussi le transfo d'alimentation et la self sous le chassis
(de toutes facons, au dessus j'avais pas la place...)
On perce ensuite les trous pour les supports de tubes, la platine de condensateurs, les CV, etc...
Verticalement la platine arduino sera fixée à gauche. L'interconnexion avec les élements de fera avec des cables de liaisons qui traverseront le chassis. Cable blindé pour la BF, cable spécial avec connecteur HF pour la platine AD9833, etc....
Les CV sont montées avec des petites platines en plexiglas. J'ai chauffé des petites plaques de plexiglass avec un décapeur thermique et je les ai coudées à 90 degrés.
Sur le CV d'antenne, j'ai une sortie verticale pour connecter celui-ci à l'antenne vissée dans le boitier. Un condensateur ajustable de 20 pf est présent pour relier la sortie HF vers le galvanomètre.
Au final le chassis ressemble à ca :
La partie alimentation avec ses diodes et les capas de 10nf en // sur chaque diode.
Le circuit de puissance BF.
La lampe de puissance HF. Le gros condo de 100nF assure la liaison pour la modulation via l'écran.
La préamplificatrice HF dont la sortie est reliée à la grille de la lampe HF.
Le code
Dans le fichier zip, à l'intérieur du sous-répertoire emetteurfa, vous trouverez le code source de l'emetteur.
L'archive avec le code