Emetteur AM avec relayage FM




finish04.jpg



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.

principe.jpg


Pour Paris, une liste de préselection de ce genre pourrait être définie comme point de départ

presets-sample.jpg



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.

nano.png


Un module de réception FM basé sur la puce SI4703. C'est un récepteur FM stéréo RDS pilotable en I2C.

module-SI4703.jpg


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

module-AD9833.jpg


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)

LCD20x4-I2C.jpg


Et un encodeur rotatif muni d'un interrupteur.

encoder.jpg


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 : Une fois le message d'accueil passé, le formatage à lieu

format.jpg



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 :
Voici ce que vous verrez à l'écran.

lcdbackground.jpg


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.

lcd-1.jpg


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.

lcd-2.jpg


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.
lcd-3.jpg


Ici uniquement le bobinage GO (LW), (le bobinage PO est court-circuité par un relais.)

lcd-3b.jpg


Ici uniquement le bobinage PO (MW), (le bobinage GO est court-circuité par l'autre relais.)

lcd-3c.jpg


On choisit donc le bobinage approprié. On valide en appuyant. Les flèches se déplacent sur le volume de réception.

lcd-4.jpg


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.

lcdbackground.jpg


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.

I2C-lcd.jpg


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.



SI4703-pinout.jpg


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.

module-AD9833.jpg


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.

AD9833-control-register.jpg


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.

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.

schema-tubes.png


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. 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.

coil-00.jpg


coil-01.jpg


Nous avons 2600µH pour le bobinage GO et 204µH pour le bobinage PO.

coil-02.jpg


coil-03.jpg


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.

circuit-coils.jpg


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.

choke01.jpg


choke02.jpg



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 :

antenna-SI4703.png


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. 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.

SI4703-mod1.jpg


SI4703-mod2.jpg


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

chassis-layout00.jpg


Le chassis

chassis-layout01.jpg


Une face avant

chassis-layout02.jpg


On fixe le chassis sur la face avant avec 4 vis.

chassis-layout03.jpg


On perce les trous pour le potard, les 2 CV, le galva, le LCD, encodeurs, interrupteurs, etc...

chassis-layout04.jpg


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...)

chassis-layout05.jpg


On perce ensuite les trous pour les supports de tubes, la platine de condensateurs, les CV, etc...

chassis-layout06.jpg


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....

chassis-layout07.jpg


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.

CV-01.jpg


CV-02.jpg


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.

CV-03.jpg


Au final le chassis ressemble à ca :

circuit-06.jpg


La partie alimentation avec ses diodes et les capas de 10nf en // sur chaque diode.

circuit-02.jpg


Le circuit de puissance BF.

circuit-03.jpg


La lampe de puissance HF. Le gros condo de 100nF assure la liaison pour la modulation via l'écran.

circuit-04.jpg


La préamplificatrice HF dont la sortie est reliée à la grille de la lampe HF.

circuit-05.jpg



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