Récepteur radio à TEF6686 + ILI9341 + SDcard.

Soit l'équivalent d'une CYD (Cheap Yellow Card) MAIS avec lecteur SDcard utilisable et 14 GPIO disponibles !

1 Le pourquoi de cette étude :

Comme je vous l'ai expliqué ( dans un précédent article ), la carte CYD bien que qualifiée de "formidable" et "merveilleuse" par nombre d'utilisateurs souffre de plusieurs défauts assez rédibitoires :
  • Le fait de ne pas pouvoir utiliser facilement le lecteur SDcard, l'afficheur et le Touchscreen ensembles dans un même programme.
  • La difficulté pour récupérer une capture d'écran sur le PC (download des fichiers SPIFFS -> PC problématique; éventuellement par hébergement d'une interface web(?)
  • Le manque cruel de ports GPIO libres sur l'ESP32 (je voudrais en particulier pouvoir utiliser des encodeurs rotatifs pas à pas)
  • Le fait de devoir utiliser l'application VScode/Platformio pour simplement mettre à jour les fichiers en mémoire SPIFFS; Insérer une SDcard compatible avec n'importe quel PC / Smartphone serait très appréciable. (on pourrait toutefois passer par une liaison WiFi / Bluetooth avec l'ESP32,)
Ce sont les raisons qui me font entreprendre le développement d'une carte personnalisée, en fait un simple circuit imprimé, reliant une Carte "ESP32 USB-C WROOM Devkit V1" et un "afficheur ILI9341 + Ecran tactile et lecteur de carte SD", avec partage optimisé des bus SPI ! J'ai passé une commande de 5 exemplaires à JLCPCB (pour 4 € les 5 , port compris).

Et voici le description d'un récepteur radio à TEF6686 qui utilise cette nouvelle carte.

2 Animation


Un gif animé composé avec quelques captures d'écran de l'afficheur, montrant la réception de stations dans la bande FM, la surveillance de fréquences présélectionnées de la bande aviation (qui nécessite l'ajout d'un convertisseur de fréquence (-110MHz) VHF->SW sur l'entrée antenne), le scan de toutes les fréquences de la bande FM, la saisie de la couleur de fond d'écran au moyen d'une palette de 32 couleurs, 16 claires et 16 sombres...

3 Le schéma de ma carte ESP32 + ILI9341 2.8

Cette nouvelle carte remplace donc la carte jaune "CYD" avec des fonctions inutiles en moins mais beaucoup de ports GPIO libres en plus.

4 Le circuit imprimé de ma carte ESP32 + ILI9341 2.8

C'est un double face. Je l'ai fait fabriquer par JLCPCB. Les documents Kicad sont disponibles dans le fichier "Documents.zip" au bas de cet article.

5 Le contrôle qualité :

C'est Ok, je te la rends !

6 Le schéma du récepteur radio SW - FM - Air band

Schéma de l'ensemble de la radio, avec la carte en question dans la partie basse, dans le cadre en tirets bleus. Où l'on voit de suite les nombreux ports GPIO disponibles pour les périphériques à venir...

Le pont de résistances R1-R2 permet de mesurer (et d'afficher) la tension de la batterie, en amont du régulaeur 5V.

7 Le module TEF6686 de chez MPX

Voir la documentation du module TEF6686 dans le fichier "documents.zip" au bas de cet article.

8 Le module ampli BF et la batterie 2s

Voir le lien plus bas.

La batterie 2s est obtenue en câblant en série deux accus Lipo 103450, placées à plat au fond du boîtier. Il faut choisir une taille (et donc capacité) compatible avec le boîtier.

9 En video




09 mars 2026 :

J'ai fait fabriquer le PCB double face par JLCPCB. (C'est la partie dans le cadre en pointillés bleu). J'attendais de le recevoir pour vous montrer le résultat, qui confirme le bon fonctionnement de cette carte. J'utilise un adaptateur SD -> microSD court (en blanc sur la partie haute) moins moche que les adaptateurs classiques. La TFcard s'insère dedans par le côté. Il me reste à connecter le module TEF6686, l'ampli BF et l'alim 5V et placer le tout dans un joli boîtier. (La vidéo ci-dessus a été prise alors que le module récepteur TEF6686 et l'ampli BF n'étaient pas encore reliés à la carte. Mais depuis j'ai testé le tout ensemble et je peux vous confirmer que ça marche).

Je vais peut être ajouter un condensateur ou deux de 1000uF sue les alim de l'afficheur et de la carte, et même utiliser deux régulateurs 5V distincts parce que j'ai constaté quelque plantages du module lorsqu'on augmente brusquement le volume sonore avec la carte alimentée uniquement par le câble usb C (sur la version câblée sur platine de prototypage (Breadboard), qui comprend le module. Soit dit en passant, oui la radio fonctionne !

10 Le récepteur dans son boîtier

J'ai plaqué (avec quelques plis !!!) une feuille de vinyle bleu, préalablement découpée avec une découpeuse 'Silhouette Portrait 3', sur la face avant.
La plaque blanche en bas à droite est gravéee au laser (NEJE Master 2s 20W).

Sur le dessus on aperçoit l'adaptateur de micro SDcard qui dépasse à peine du boîtier.

11 Le code source main.cpp

CODE SOURCE en C++
  1. /* ************************************************************************************
  2. Radio TEF6686 par Silicium628
  3. pour ma carte (fab : JLCPCB) ESP32 Wroom + afficheur 2.8" TFT 240x320 + SDcard
  4.  
  5. Cette version utilise la SDcard
  6.  
  7. ************************************************************************************ */
  8.  
  9. // REMARQUES:
  10. // 1) lorsque la carte est connectée sur un bus USB de l'ordinateur,
  11. // un terminal série tel que CuteCom affichera beaucoup de choses en temps réel.
  12. // 2) Pour s'y retrouver dans le code, le plus simple est de partir de la fonction 'loop()' qui appelle les autres
  13. // 3) Le fichier User_Setup dans le dossier 'lib/TFT_eSPI' est spécifique à cette configuration
  14. // pour ce qui concerne les connexions mais aussi les limitations de fréquence du bus SPI
  15.  
  16. #include <Arduino.h>
  17. #include "main.h"
  18. //#include "Tuner_Patch_Lithio_V102_p224.h" // voir la fonction 'Tuner_Patch()' dans la fonction 'setup()'
  19.  
  20. String version = "1.11.0"; // (avec enregistrement sur SD card)
  21.  
  22. #include "FS.h"
  23. #include "SD.h"
  24. #include "Wire.h"
  25. #include <stdint.h>
  26.  
  27. #include <Free_Fonts.h>
  28. #include "TFT_eSPI.h" // Hardware-specific library
  29. #include "SPI.h"
  30. #include "Digit_Font.h"
  31. #include <XPT2046_Touchscreen.h>
  32.  
  33.  
  34. #include "constantes_628.h"
  35. #include "Couleurs_AEC.h"
  36. #include "DSP_INIT_628.h"
  37. #include "driverTEF6686_628.h"
  38.  
  39. #define SPI_READ_FREQUENCY 16000000
  40.  
  41. #define bande_SW (frequence > 1500) && (frequence < 28000)
  42. #define bande_interdite1 (frequence > 28000) && (frequence < 88000)
  43. #define bande_interdite2 (frequence > 108000) && (frequence < 118000)
  44. #define bande_FM (frequence >= 88000) && (frequence < 108000)
  45. #define bande_AIR (frequence >= 118000) && (frequence < 138000)
  46.  
  47. #define XPT2046_IRQ 36
  48. #define XPT2046_MOSI 32 //T_DI 32
  49. #define XPT2046_MISO 39 //T_DO 39
  50. #define XPT2046_CLK 25
  51. #define XPT2046_CS 33
  52.  
  53. //sur le connecteur CN1 de la carte CYD sérigraphiée 'ESP32-2432S028';
  54. //attention: ces valeurs ne sont pas celles par défaut pour SDA et SCL
  55. const int GPIO_SDA = 21;
  56. const int GPIO_SCL = 22;
  57.  
  58. const int analogPin = 35;
  59.  
  60. const int GPIO_BL = 4; // pour LED backlight ILI9341
  61.  
  62. const int _DX = 320;
  63. const int _DY = 240;
  64.  
  65. #define High_16bto8b(a) ((uint8_t)((a) >> 8))
  66. #define Low_16bto8b(a) ((uint8_t)(a ))
  67. #define Convert8bto16b(a) ((uint16_t)(((uint16_t)(*(a))) << 8 |((uint16_t)(*(a+1)))))
  68.  
  69. SPIClass mySpi = SPIClass(VSPI);
  70. XPT2046_Touchscreen ts(XPT2046_CS, XPT2046_IRQ);
  71.  
  72. SPIClass mySpi2 = SPIClass(HSPI);
  73.  
  74. TFT_eSPI TFT = TFT_eSPI(); // Configurer le fichier User_Setup.h de la bibliothèque TFT_eSPI au préalable
  75.  
  76. TFT_eSprite sprite_frq = TFT_eSprite(&TFT);
  77. TFT_eSprite sprite_ligne1 = TFT_eSprite(&TFT);
  78.  
  79.  
  80. struct ETALON_TS // etalon touch screen
  81. {
  82. int16_t x0;
  83. int16_t dx;
  84. int16_t y0;
  85. int16_t dy;
  86. };
  87.  
  88. ETALON_TS eTS;
  89.  
  90.  
  91. struct POINT
  92. {
  93. uint16_t x;
  94. uint16_t y;
  95. };
  96.  
  97. // coordonnées des points de calibrage de l'écran tactile
  98. // (calibration ? étalonnage ?? ajustage ??? boaf, m'enfin !!)
  99. POINT A, B;
  100.  
  101. uint16_t x_touch, y_touch;
  102. uint16_t memo_x_touch, memo_y_touch;
  103. uint16_t memo_tiret_H[20];
  104. uint16_t memo_tiret_V[20];
  105. uint16_t valeur_bargraph=0;
  106.  
  107. uint8_t SDcardOk=0;
  108. uint16_t color565px;
  109. boolean stop = false;
  110.  
  111. float raddeg = M_PI/180.0;
  112. float deg_to_rad = 2.0 * M_PI /360.0;
  113.  
  114. boolean test_touch_screen = false; // mettre true pour activer le test
  115.  
  116. uint16_t compteur1 = 0;
  117. uint16_t compteur2 = 0;
  118. uint16_t compteur3 = 0;
  119. uint8_t num_capture = 0;
  120.  
  121. uint32_t frequence=10000;
  122. uint32_t saut_freq;
  123. uint16_t seuil = 50;
  124. uint16_t memo_seuil = 50;
  125.  
  126. GROUPE_FREQUENCES groupe_SW;
  127. GROUPE_FREQUENCES groupe_FM;
  128. GROUPE_FREQUENCES groupe_AIR;
  129. GROUPE_FREQUENCES groupe_SCAN;
  130.  
  131. uint32_t frq_preset_SW[8]; // 8 fréquences attribuées aux boutons [preset1] à [preset8] soit 8x4=32 octets
  132. uint32_t frq_preset_FM[8]; // 8 fréquences attribuées aux boutons [preset1] à [preset8] soit 8x4=32 octets
  133. uint32_t frq_preset_AIR[8];// 8 fréquences attribuées aux boutons [preset1] à [preset8] soit 8x4=32 octets total 32*3 = 96 octets
  134.  
  135. uint32_t memo_freq;
  136. uint16_t frq_preset_adr_0;
  137. String frequence_txt = "";
  138.  
  139. TOUCH_BOUTON bt_info;
  140. TOUCH_BOUTON bt_capture; // capture écran
  141. TOUCH_BOUTON bt_sleep;
  142. TOUCH_BOUTON bt_quiet; // calme (anti-parasites)
  143. TOUCH_BOUTON bt_TEST;
  144.  
  145. TOUCH_BOUTON bt_mode_FRQ, bt_mode_MEM;
  146. TOUCH_BOUTON bt_plus, bt_moins;
  147.  
  148. TOUCH_BOUTON bt_SD_write, bt_erase_1F, bt_LST; //, bt_SD_LST, bt_SD_RAZ;
  149. TOUCH_BOUTON bt_1, bt_2, bt_3, bt_4, bt_5, bt_6; // 6 boutons au dessus des chiffres de la fréquence
  150. TOUCH_BOUTON bt_coul;
  151. TOUCH_BOUTON bt_coul_to_SD;
  152.  
  153. TOUCH_BOUTON Bt_SCAN, bt_scan_air;
  154. TOUCH_BOUTON bt_scan_SW, bt_scan_FM;
  155.  
  156. TOUCH_BOUTON bt_RST_affi; // "ok"
  157.  
  158. TOUCH_BOUTON bt_LEV, bt_SNR, bt_re_scan, bt_scan_suivant;
  159. TOUCH_BOUTON bt_seuil_plus, bt_seuil_moins;
  160.  
  161.  
  162. // ---------- gridPad ------------
  163. GRID_PAD gridPad1;
  164.  
  165. // ---------- numPad ------------
  166. NUM_PAD numPad1;
  167.  
  168. // ---------- presetPad1 ------------
  169. PRESET_PAD presetPad1;
  170.  
  171. // ---------- swPad1 ------------
  172. SW_PAD swPad1;
  173.  
  174. // -------------------------------
  175. TOUCH_BOUTON bt_SW, bt_FM, bt_AIR, bt_SCN;
  176. TOUCH_BOUTON bt_LED;
  177. TOUCH_BOUTON bt_mute;
  178. TOUCH_BOUTON bt_reset;
  179. TOUCH_BOUTON bt_cal;
  180. TOUCH_BOUTON bt_stop_scan;
  181.  
  182. TOUCH_BOUTON bt_set; // attribtion d'une fréquence à un des 8 boutons preset
  183. TOUCH_BOUTON bt_annuler; // "x"
  184. TOUCH_BOUTON bt_close; // "x"
  185.  
  186. //les variables globales sont le Mal, et il faut éviter à tous prix de s'en servir, m'enfin!
  187. boolean mute;
  188. boolean vu_metre_actif;
  189.  
  190. enum MODE_AFFI {COUL, NORMAL, SCAN_F, SCAN_M, SET_F_PRESET}; //[couleur], [normal], [scan], [set 1F pour 1Bt]
  191. MODE_AFFI mode_affi;
  192.  
  193. enum MODE_SELECT {_FRQ=0, _MEM=1} mode_s; // mode de mofif fréquence, en tapant les chiffres /ou en mémoire
  194.  
  195. enum MODUL {AM, WFM};
  196. MODUL modulation_active;
  197.  
  198. enum BANDE {SW, FM, AIR, SCN}; //fréquences;
  199. BANDE bande_active;
  200.  
  201. enum GRP_ACT {gSW, gFM, gAIR, gSCN}; // groupes mémoire SW, FM, AIR, SCN; le grp SCN mémorise le résultat d'un scan FREQUENCE
  202. GRP_ACT groupe_actif;
  203.  
  204. enum MODE_SCAN {FREQUENCE, MEMOIRE};
  205. MODE_SCAN mode_scan;
  206.  
  207. enum MODE_SEUIL {LEV, SNR}; // level ou signal/bruit
  208. MODE_SEUIL mode_seuil;
  209.  
  210. boolean quiet = false;
  211.  
  212. uint16_t FRQ_x0;
  213. uint16_t FRQ_y0;
  214.  
  215. uint16_t x0_box_SD;
  216. uint16_t y0_box_SD;
  217.  
  218. uint16_t x0_box_PRESET;
  219. uint16_t y0_box_PRESET;
  220.  
  221. uint16_t x0_box_GROUPE; // SW - FM - AIR
  222. uint16_t y0_box_GROUPE;
  223.  
  224. uint16_t x0_box_boutons_scan;
  225. uint16_t y0_box_boutons_scan;
  226.  
  227. uint16_t x0_box_SCAN; // grande surface d'affichage
  228. uint16_t y0_box_SCAN;
  229. uint16_t dx_box_SCAN;
  230. uint16_t dy_box_SCAN;
  231.  
  232. uint16_t x0_numPad;
  233. uint16_t y0_numPad;
  234.  
  235. uint16_t x0_vu_metre;
  236. uint16_t y0_vu_metre;
  237.  
  238. uint16_t x0_box_info1; // en bas à gauche
  239. uint16_t y0_box_info1;
  240.  
  241. uint16_t x0_box_info2; // à la place du vu-metre
  242. uint16_t y0_box_info2;
  243. uint16_t dx_box_info2;
  244. uint16_t dy_box_info2;
  245.  
  246. uint16_t x0_gridPad;
  247. uint16_t y0_gridPad;
  248. uint16_t dx_gridPad;
  249. uint16_t dy_gridPad;
  250.  
  251. uint16_t x0_saisie;
  252. uint16_t y0_saisie;
  253.  
  254. uint16_t x0_choix_couleur;
  255. uint16_t y0_choix_couleur;
  256.  
  257. uint8_t n_appui; // incrémenté à chaque appui sur une touche du numPad numérique
  258. uint32_t total_saisi;
  259.  
  260.  
  261. uint16_t status;
  262. int16_t level;
  263. uint16_t usn;
  264. uint16_t wam;
  265. int16_t offset;
  266. uint16_t bandwidth;
  267. uint16_t mod;
  268. int8_t snr;
  269.  
  270. uint16_t A_block;
  271. uint16_t B_block;
  272. uint16_t C_block;
  273. uint16_t D_block;
  274. uint16_t dec_error;
  275.  
  276. float position_aiguille; // vu-metre
  277. float valeur_affi;
  278. float memo_valeur_affi;
  279. float ltx; // aiguille
  280. uint16_t osx;
  281. uint16_t osy;
  282.  
  283. uint16_t couleur_traits = GRIS_5;
  284. uint16_t JAUNE_chiffres = 65504;
  285. uint16_t VERT_chiffres = 2016;
  286.  
  287. uint8_t cR = 0;
  288. uint8_t cG = 0;
  289. uint8_t cB = 0;
  290. uint16_t couleur_fond_ecran = VERT_FONCE;
  291.  
  292. String s_recue;
  293. String memo_s_recue="";
  294.  
  295.  
  296.  
  297. float degTOrad(float angle)
  298. {
  299. return (angle * M_PI / 180.0);
  300. }
  301.  
  302.  
  303. uint8_t decToBcd( int val )
  304. {
  305. return (uint8_t) ((val / 10 * 16) + (val % 10));
  306. }
  307.  
  308.  
  309. uint16_t Color_To_565(uint8_t r, uint8_t g, uint8_t b)
  310. {
  311. return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3);
  312. }
  313.  
  314.  
  315. void RGB565_to_888(uint16_t color565, uint8_t *R, uint8_t *G, uint8_t *B)
  316. {
  317. *R=(color565 & 0xF800) >> 8;
  318. *G=(color565 & 0x7E0) >> 3;
  319. *B=(color565 & 0x1F) << 3 ;
  320. }
  321.  
  322.  
  323.  
  324. void init_variables_globales()
  325. // je ne les initialise pas lors de leur déclaration sinon lors d'un reset logiciel (appel de la fonction 'setup()'
  326. // par le boouton 'RST') elles ne seraient pas réinitialisées
  327. {
  328. // étalonnage touch screen
  329. eTS.x0 = -30; eTS.y0 = -30;
  330. eTS.dx = 11; eTS.dy = 14;
  331.  
  332. mode_affi = NORMAL;
  333. bande_active = FM;
  334. modulation_active = WFM;
  335. mode_s = _MEM;
  336. mode_scan = FREQUENCE;
  337. mode_seuil = LEV;
  338. mute = false;
  339. vu_metre_actif = true;
  340.  
  341. FRQ_x0 = 50; FRQ_y0 = 30;
  342. x0_box_SD = 2; y0_box_SD = 150;
  343. x0_box_PRESET =2; y0_box_PRESET =87;
  344. x0_box_GROUPE = 205; y0_box_GROUPE = 115;
  345. x0_box_boutons_scan = 2; y0_box_boutons_scan = 105;
  346.  
  347. // grande surface d'affichage
  348. x0_box_SCAN = 2; y0_box_SCAN = 90;
  349. dx_box_SCAN = 315; dy_box_SCAN = 148;
  350.  
  351. x0_numPad = 70; y0_numPad = 115;
  352. x0_vu_metre = 170; y0_vu_metre = 140;
  353. x0_box_info1 = 2; y0_box_info1 = 220;
  354.  
  355. x0_box_info2 = x0_vu_metre; y0_box_info2 = y0_vu_metre;
  356. dx_box_info2 = 140; dy_box_info2 = 70;
  357.  
  358. x0_gridPad = x0_vu_metre;
  359. y0_gridPad = y0_vu_metre;
  360. dx_gridPad = 140; dy_gridPad = 70;
  361.  
  362. x0_saisie = 2; y0_saisie = 2;
  363. x0_choix_couleur = 170; y0_choix_couleur = 145;
  364.  
  365. n_appui = 0; // incrémenté à chaque appui sur une touche du numPad numérique
  366. total_saisi = 0;
  367.  
  368. valeur_bargraph=0;
  369.  
  370. position_aiguille = 0; // vu-metre
  371. valeur_affi = 0;
  372. memo_valeur_affi = 0;
  373. ltx = 0; // aiguille
  374. osx = x0_vu_metre;
  375. osy = y0_vu_metre;
  376. }
  377.  
  378.  
  379. //uint16_t bmp_offset = 0;
  380. uint16_t bmp_width;
  381. uint16_t bmp_heigh;
  382.  
  383.  
  384.  
  385.  
  386. void draw_bmp565(uint16_t x0, uint16_t y0, uint8_t sens, File* fp)
  387. {
  388. uint16_t i,j;
  389. uint16_t y1;
  390. uint8_t bmp_data[2]={0};
  391. uint16_t bmp_color[2];
  392.  
  393. fp->seek(0);
  394. for(i=0; i<bmp_heigh; i++)
  395. {
  396. for(j=0; j<(bmp_width); j++)
  397. {
  398. fp->read(bmp_data, 2); // lit les 2 octets constituant la valeur rgb565 et les place dans bmp_data[]
  399. if (sens == 0) {y1 = y0+bmp_heigh-i;}
  400. else {y1 = y0+i;}
  401. TFT.drawPixel(x0+j, y1, bmp_data[0] + (bmp_data[1] << 8) );
  402. }
  403. }
  404. }
  405.  
  406.  
  407.  
  408. // Fonction optimisée pour l'afficheur ILI9341 320x240 avec la library 'TFT_eSPI'
  409. // ne convient PAS pour les ESP32 Wroom + afficheur 3.5" TFT 480x320
  410. void write_TFT_on_SDcard() // enregistre image bmp 320x240 RGB565 (5+6+5 = 16bits/px)
  411. {
  412. Serial.println("write_TFT_on_SDcard()");
  413.  
  414. if (SDcardOk==0) {return;}
  415. int32_t x, y;
  416. uint16_t color565;
  417.  
  418. uint8_t lineBuffer8[(320*2)];
  419. uint16_t lineBuffer16[320];
  420. uint8_t octet_A, octet_B;
  421. String s1;
  422.  
  423. s1 +="/bmp565/capture";
  424. s1 += String(num_capture);
  425. s1 += ".bmp" ;
  426.  
  427. File file1 = SD.open(s1, FILE_WRITE); // crée le fichier si pas présent
  428. if (file1)
  429. {
  430. // création entête bmp565 - 138 octets; voir bmp565_header[] dans le fichier main.h
  431. for(uint8_t i=0; i<138; i++) { file1.write(bmp565_header[i]); }
  432.  
  433. for (int16_t y=239; y>=0; y--)
  434. {
  435. TFT.readRect(0, y, 320, 1, lineBuffer16); // lit une ligne
  436. TFT.drawString("A", 200, 200); // pour terminer par une écriture
  437.  
  438. uint16_t i=0;
  439. for (int16_t x=0; x<320; x++) //320
  440. {
  441. color565px = lineBuffer16[x]; // BBBBBrrr rrrVVVVV
  442. octet_A = (color565px & 0b1111111100000000) >> 8;
  443. octet_B = (color565px & 0b0000000011111111);
  444.  
  445. lineBuffer8[i] = octet_A;
  446. lineBuffer8[i+1] = octet_B;
  447. i+=2;
  448. }
  449. file1.write(lineBuffer8, sizeof(lineBuffer8));
  450. }
  451. num_capture ++;
  452. TFT.fillScreen(NOIR);
  453. TFT.setTextColor(BLANC, NOIR);
  454. TFT.setFreeFont(FF1);
  455. TFT.drawString("Capture ok", 20, 100);
  456. delay(1000);
  457. init_affichages();
  458. }
  459. }
  460.  
  461.  
  462. void affiche_index_frq() // 6 petits boutons juste au dessus de chaque chiffre pour indiquer celui à modifier
  463. {
  464. int x = FRQ_x0 +15;
  465. int y = FRQ_y0 - 5;
  466. uint16_t c1 = NOIR;
  467. uint16_t c2 = VERT;
  468.  
  469. bt_1.init(x, y, 20, 5, 0, GRIS_5); bt_1.affiche(c2, 1); x+=31;
  470. bt_2.init(x, y, 20, 5, 0, GRIS_5); bt_2.affiche(c2, 1); x+=31;
  471. bt_3.init(x, y, 20, 5, 0, GRIS_5); bt_3.affiche(c2, 1); x+=46;
  472. bt_4.init(x, y, 20, 5, 0, GRIS_5); bt_4.affiche(c2, 1); x+=31;
  473. bt_5.init(x, y, 20, 5, 0, GRIS_5); bt_5.affiche(c2, 1); x+=31;
  474. bt_6.init(x, y, 20, 5, 0, GRIS_5); bt_6.affiche(c2, 1);
  475. }
  476.  
  477.  
  478. void efface_index_frq() // les 6 petits boutons
  479. {
  480. int x = FRQ_x0 +15;
  481. int y = FRQ_y0 - 5;
  482.  
  483. TFT.fillRect(x, y, 190, 5, couleur_fond_ecran);
  484. }
  485.  
  486.  
  487.  
  488.  
  489. void init_boutons_Plus_Moins()// boutons '<' et '>'
  490. {
  491. int x0 = 240;
  492. int y0 = 90;
  493.  
  494. String s1, s2;
  495.  
  496. uint16_t c1 = GRIS_6;
  497. uint16_t c2 = JAUNE;
  498.  
  499. if(mode_s == _FRQ) { s1 = " -"; s2 = " +"; }
  500. if(mode_s == _MEM) { s1 = " <"; s2 = " >"; }
  501.  
  502. bt_moins.init(x0, y0, 30, 15, 3, GRIS_5);
  503. bt_moins.cliked = false;
  504. bt_moins.label= s1;
  505.  
  506. bt_plus.init(x0+35, y0, 30, 15, 3, GRIS_5);
  507. bt_plus.cliked = false;
  508. bt_plus.label= s2;
  509. }
  510.  
  511.  
  512. void init_boutons_GROUPE() // groupe de fréquence (SW - FM - AIR - SCAN)
  513. {
  514. uint16_t x = x0_box_GROUPE+4;
  515. uint16_t y = y0_box_GROUPE+5;
  516.  
  517. TFT.setFreeFont(FF0);
  518.  
  519. bt_SW.init(x, y, 20, 15, 3, GRIS_5);
  520. bt_SW.cliked = false;
  521. bt_SW.selected = false;
  522. bt_SW.label="SW";
  523. x+=25;
  524.  
  525. bt_FM.init(x, y, 20, 15, 3, GRIS_5);
  526. bt_FM.cliked = false;
  527. bt_FM.selected = false;
  528. bt_FM.label="FM";
  529. x+=25;
  530.  
  531. bt_AIR.init(x, y, 22, 15, 3, GRIS_5);
  532. bt_AIR.cliked = false;
  533. bt_AIR.selected = false;
  534. bt_AIR.label="AIR";
  535. x+=27;
  536.  
  537. bt_SCN.init(x, y, 20, 15, 3, GRIS_5);
  538. bt_SCN.cliked = false;
  539. bt_SCN.selected = false;
  540. bt_SCN.label="SC";
  541.  
  542. }
  543.  
  544.  
  545. void init_1_bouton(uint8_t n_font, uint16_t xi, uint16_t yi, uint8_t dx, uint8_t dy, String si, TOUCH_BOUTON *bouton_i)
  546. {
  547. uint16_t c1 = GRIS_5;
  548. uint16_t c2 = BLANC;
  549.  
  550. bouton_i->init(xi, yi, dx, dy, 3, GRIS_5);
  551. bouton_i->cliked = false;
  552. bouton_i->selected = false;
  553. bouton_i->label = si;
  554. bouton_i->affiche(c2, n_font);
  555. }
  556.  
  557.  
  558. void init_1_bouton_rouge(uint8_t n_font, uint16_t xi, uint16_t yi, uint8_t dx, uint8_t dy, String si, TOUCH_BOUTON *bouton_i)
  559. {
  560. uint16_t c2 = BLANC;
  561.  
  562. bouton_i->init(xi, yi, dx, dy, 3, ROUGE);
  563. bouton_i->cliked = false;
  564. bouton_i->selected = false;
  565. bouton_i->label = si;
  566. bouton_i->affiche(c2, n_font);
  567. }
  568.  
  569.  
  570. void init_boutons_MODE() // en haut à gauche
  571. {
  572. uint16_t c1 = NOIR;
  573. uint16_t c2 = VERT;
  574.  
  575. TFT.setFreeFont(FF0);
  576. TFT.setTextColor(GRIS_3, NOIR);
  577. TFT.drawString("mode", 6, 24);
  578.  
  579. TFT.drawFastVLine(45, 15, 72, couleur_traits);
  580.  
  581. bt_mode_FRQ.init(5, 35, 37, 20, 2, GRIS_5);
  582. bt_mode_FRQ.selected = false;
  583. bt_mode_FRQ.label="FRQ";
  584. bt_mode_FRQ.affiche(c2, 2);
  585.  
  586. bt_mode_MEM.init(5, 60, 37, 20, 2, GRIS_5);
  587. bt_mode_MEM.selected = true;
  588. bt_mode_MEM.label="MEM";
  589. bt_mode_MEM.affiche(c2, 2);
  590.  
  591. affiche_index_frq();
  592. }
  593.  
  594.  
  595. void affiche_1_bt_RGB(TOUCH_BOUTON *bouton_i, uint16_t x, uint16_t y, uint8_t dx, uint16_t couleur, String s_i)
  596. {
  597. uint16_t c1 = couleur;
  598. uint16_t c2 = JAUNE;
  599.  
  600. bouton_i->init(x, y, dx, 14, 3, GRIS_5);
  601. bouton_i->cliked = false;
  602. bouton_i->selected = false;
  603. bouton_i->label = s_i;
  604. bouton_i->affiche(c2, 1);
  605. }
  606.  
  607.  
  608. void init_sprites()
  609. {
  610. sprite_frq.createSprite(220, 55);
  611. sprite_frq.loadFont(digitfont1);
  612. sprite_frq.setTextColor(JAUNE_2, NOIR);
  613. sprite_frq.setTextDatum(MR_DATUM); // alignement du texte
  614.  
  615. }
  616.  
  617.  
  618. void Tuner_Reset(void)
  619. {
  620. Wire.beginTransmission(0x64);
  621. Wire.write(0x1e);
  622. Wire.write(0x5a);
  623. Wire.write(0x01);
  624. Wire.write(0x5a);
  625. Wire.write(0x5a);
  626. Wire.endTransmission();
  627. }
  628.  
  629. /*
  630. static void Tuner_Patch_Load(const unsigned char *pLutBytes, uint16_t size)
  631. {
  632.   unsigned char buf[24 + 1];
  633.   uint16_t i, len;
  634.   uint16_t r;
  635.   buf[0] = 0x1b;
  636.   while (size)
  637.   {
  638.   len = (size > 24) ? 24 : size;
  639.   size -= len;
  640.   for (i = 0; i < len; i++) buf[1 + i] = pgm_read_byte(&pLutBytes[i]);
  641.   pLutBytes += len;
  642.   if (1 != (r = Tuner_WriteBuffer(buf, len + 1))) break;
  643.   }
  644. }
  645.  
  646. void Tuner_Patch()
  647. {
  648. Tuner_Reset();
  649. delay(100);
  650. Wire.beginTransmission(0x64);
  651. Wire.write(0x1c);
  652. Wire.write(0x00);
  653. Wire.write(0x00);
  654. Wire.endTransmission();
  655. delay(100);
  656. Wire.beginTransmission(0x64);
  657. Wire.write(0x1c);
  658. Wire.write(0x00);
  659. Wire.write(0x74);
  660. Wire.endTransmission();
  661. Tuner_Patch_Load(pPatchBytes102, PatchSize102);
  662. Wire.beginTransmission(0x64);
  663. Wire.write(0x1c);
  664. Wire.write(0x00);
  665. Wire.write(0x00);
  666. Wire.endTransmission();
  667. delay(100);
  668. Wire.beginTransmission(0x64);
  669. Wire.write(0x1c);
  670. Wire.write(0x00);
  671. Wire.write(0x75);
  672. Wire.endTransmission();
  673.   Tuner_Patch_Load(pLutBytes102, LutSize102);
  674. Wire.beginTransmission(0x64);
  675. Wire.write(0x1c);
  676. Wire.write(0x00);
  677. Wire.write(0x00);
  678. Wire.endTransmission();
  679. }
  680. */
  681.  
  682.  
  683. bool Tuner_Table_Write(const unsigned char *tab)
  684. {
  685. if (tab[1] == 0xff)
  686. {
  687. delay(tab[2]);
  688. return 1;
  689. }
  690. else { return Tuner_WriteBuffer((unsigned char *)&tab[1], tab[0]); }
  691. }
  692.  
  693.  
  694. void Tuner_Init(const unsigned char *table)
  695. {
  696. uint16_t r;
  697. const unsigned char *p = table;
  698.  
  699. for (uint16_t i = 0; i < sizeof(tuner_init_tab9216); i += (pgm_read_byte(p + i) + 1))
  700. {
  701. if (1 != (r = Tuner_Table_Write(p + i))) break;
  702. }
  703. }
  704.  
  705.  
  706. void Tune_Frequence(uint32_t Fi)
  707. {
  708. TFT.setFreeFont(FF0);
  709. //TFT.setTextColor(BLEU, NOIR);
  710. String s1 = String(Fi);
  711. //TFT.drawString(s1, 80, 2);
  712.  
  713. quiet = false; // anti-parasites
  714. bt_quiet.selected = false;
  715. bt_quiet.affiche(VERT, 1);
  716.  
  717. frequence = Fi;
  718.  
  719. if (Fi == 1500)
  720. {
  721. TFT.setTextColor(ROUGE, NOIR);
  722. TFT.drawString("MINIMUM ", 130, 2);
  723. }
  724.  
  725. if (bande_SW)
  726. {
  727. modulation_active = AM;
  728. Tune_Frequence_AM(Fi);
  729. TFT.setTextColor(VERT, NOIR);
  730. efface_box_entete2();
  731. TFT.drawString("SW ", 130, 2);
  732. }
  733.  
  734. if (bande_interdite1)
  735. {
  736. efface_box_entete2();
  737. TFT.setTextColor(ROUGE, NOIR);
  738. TFT.drawString("FRQ non disponible", 80, 2);
  739. }
  740.  
  741. if (bande_FM)
  742. {
  743. modulation_active = WFM;
  744. Tune_Frequence_FM(Fi/10); // envoi les data au TEF6686
  745. efface_box_entete2();
  746. TFT.setTextColor(VERT, NOIR);
  747. TFT.drawString("bande FM", 130, 2);
  748. }
  749.  
  750. if (bande_interdite2)
  751. {
  752. efface_box_entete2();
  753. TFT.setTextColor(ROUGE, NOIR);
  754. TFT.drawString("FRQ NON DISPONIBLE", 80, 2);
  755. }
  756.  
  757. if (bande_AIR)
  758. {
  759. modulation_active = AM;
  760. Tune_Frequence_AM(Fi-110000); // nécessite un convertisseur de fréquence 110MHz en entrée antenne
  761. TFT.setTextColor(BLEU_CLAIR, NOIR);
  762. efface_box_entete2();
  763. TFT.drawString("AIR BAND", 130, 2);
  764. }
  765.  
  766. if (Fi == 138000)
  767. {
  768. TFT.setTextColor(ROUGE, NOIR);
  769. efface_box_entete2();
  770. TFT.drawString("F MAX ", 130, 2);
  771. }
  772. }
  773.  
  774.  
  775. void load_GRP_FREQ_SD() // SD --> to RAM
  776. {
  777. Serial.println("--- Frequences lues sur la SDcard ---------------");
  778. Serial.println(" ");
  779.  
  780. Serial.println("GROUPE SW");
  781. groupe_SW.RAZ(); // important, sinon les fréquences se trouvent dédoublées lors d'un soft-reset
  782. groupe_SW.load_bloc(); // SD --> RAM
  783. groupe_SW.tri_bloc(); // en RAM
  784. groupe_SW.bloc_to_serial();
  785.  
  786. Serial.println("---------------------------------------------");
  787.  
  788. Serial.println("GROUPE FM");
  789. groupe_FM.RAZ();
  790. groupe_FM.load_bloc();
  791. groupe_FM.tri_bloc();
  792. groupe_FM.bloc_to_serial();
  793.  
  794. Serial.println("---------------------------------------------");
  795.  
  796. Serial.println("GROUPE AIR");
  797. groupe_AIR.RAZ();
  798. groupe_AIR.load_bloc();
  799. groupe_AIR.tri_bloc();
  800. groupe_AIR.bloc_to_serial();
  801.  
  802. Serial.println("---------------------------------------------");
  803.  
  804. // remarque : le groupe SCAN n'est jamais enregistré
  805. }
  806.  
  807.  
  808. uint16_t brightness(uint16_t couleur)
  809. {
  810. uint8_t r, g, b;
  811.  
  812. r = 0xFF & (couleur >> 16);
  813. g = 0xFF & (couleur >> 8);
  814. b = 0xFF & couleur;
  815.  
  816. return ( r + g + b );
  817. }
  818.  
  819.  
  820. void init_SDcard()
  821. {
  822. Serial.println("---------------------");
  823. Serial.println("init_SDcard()");
  824. String s1;
  825.  
  826. TFT.fillRect(0, 0, 480, 320, NOIR); // efface
  827. TFT.setTextColor(BLANC, NOIR);
  828. TFT.setFreeFont(FF1);
  829.  
  830. if(!SD.begin(5, mySpi2))
  831. {
  832. Serial.println("Card Mount Failed");
  833. SDcardOk=0;
  834. }
  835. else
  836. {
  837. Serial.println("SDcard OK");
  838. SDcardOk=1;
  839. TFT.fillRect(0, 0, 480, 320, VERT);
  840. delay(100);
  841. }
  842.  
  843. uint8_t cardType = SD.cardType();
  844.  
  845. if(cardType == CARD_NONE)
  846. {
  847. Serial.println("NO SDcard");
  848. SDcardOk=0;
  849. return;
  850. }
  851.  
  852. Serial.print("SDcard Type: ");
  853. if(cardType == CARD_SD) {Serial.print("SDSC");}
  854. else if(cardType == CARD_SDHC) {Serial.println("SDHC");}
  855.  
  856. uint32_t cardSize = SD.cardSize() / (1024 * 1024);
  857. s1=(String)cardSize + " GB";
  858. Serial.println(s1); Serial.println();
  859.  
  860. delay (100);
  861. TFT.fillRect(0, 0, 480, 320, NOIR); // efface
  862. }
  863.  
  864.  
  865. void init_affichages()
  866. {
  867. Serial.println("init_affichages()");
  868. TFT.fillRect(0, 0, 319, 239, couleur_fond_ecran);
  869. efface_box_entete1();
  870. efface_box_entete2();
  871. efface_box_entete3();
  872. if (brightness(couleur_fond_ecran) > 500) {couleur_traits = NOIR;} else {couleur_traits = BLANC;}
  873.  
  874. TFT.setTextColor(JAUNE, NOIR);
  875.  
  876. TFT.drawRect(0, 0, 319, 240, couleur_traits); // cadre principal pourtour de l'écran
  877. TFT.setFreeFont(FF0);
  878. TFT.setTextColor(BLANC, BLEU);
  879. String s1 = "v:" + version;
  880. TFT.drawString(s1, 45, 15);
  881.  
  882.  
  883. while (!Serial && (millis() <= 1000));
  884. init_boutons_MODE();
  885.  
  886. affiche_box_SD();
  887. init_1_bouton(1, x0_box_SD+4, y0_box_SD+16, 40, 15, " LST", &bt_LST);
  888. init_1_bouton(1, x0_box_SD+4, y0_box_SD+33, 40, 15, "Write", &bt_SD_write);
  889.  
  890. TFT.setFreeFont(FF0);
  891.  
  892. init_boutons_Plus_Moins();
  893. init_boutons_GROUPE(); // (SW - FM - AIR - SC)
  894.  
  895. init_1_bouton(1, 305, 15, 15, 15, "?", &bt_info);
  896. init_1_bouton(1, 2, 15, 10, 10, "C", &bt_capture);
  897.  
  898. uint16_t xi, yi, dx, dy;
  899.  
  900. //1ere ligne, celle du dessus
  901. xi = 167; yi = 212; dx = 35; dy = 11;
  902. init_1_bouton(1, xi, yi, dx, dy, " LED", &bt_LED); xi+=3*dx+3*2; // LED backlight
  903. init_1_bouton(1, xi, yi, dx, dy, " CAL", &bt_cal); xi+=dx+2;
  904.  
  905.  
  906. //2eme ligne, en dessous
  907. xi = 130; yi = 224; dx = 35; dy = 11;
  908. init_1_bouton(1, xi, yi, dx, dy, "Mute", &bt_mute); xi+=dx+2;
  909. init_1_bouton(1, xi, yi, dx, dy, "sleep", &bt_sleep); xi+=dx+2;
  910. init_1_bouton(1, xi, yi, dx, dy, "quiet", &bt_quiet); xi+=dx+2;
  911. init_1_bouton(1, xi, yi, dx, dy, " RST", &bt_reset); xi+=dx+2;
  912. init_1_bouton(1, xi, yi, dx, dy, "Color", &bt_coul); xi+=dx+2;
  913.  
  914. init_1_bouton(1, 160, 120, 40, 14, "TEST", &bt_TEST);
  915.  
  916. TFT.fillRect(x0_box_boutons_scan, y0_box_boutons_scan + 10, 60, 25, NOIR);
  917. init_1_bouton(2, 5, 118, 55, 20, "SCAN", &Bt_SCAN);
  918. //init_1_bouton(1, 5, 135, 55, 15, "scan AIR", &bt_scan_air);
  919.  
  920. init_1_bouton(1, 168, 97, 30, 15, "set", &bt_set);
  921.  
  922. init_1_bouton(1, x0_box_SD+4, y0_box_SD+33, 40, 15, "Write", &bt_SD_write);
  923. init_1_bouton(1, x0_box_SD+4, y0_box_SD+50, 40, 15, "raz 1F", &bt_erase_1F);
  924.  
  925. numPad1.init(x0_numPad, y0_numPad, true);
  926.  
  927. affiche_box_presets(); // conteneur des 8 petits boutons
  928. presetPad1.init(x0_box_PRESET +5, y0_box_PRESET +5);
  929.  
  930. efface_box_entete2();
  931. efface_box_entete3();
  932.  
  933. init_box_info();
  934. affiche_box_FRQ(GRIS_3); // autour de la fréquence (gros chiffres JAUNE ou VERT)
  935.  
  936. if (mode_affi == NORMAL)
  937. {
  938. affiche_box_GROUPE();
  939. bt_moins.affiche(VERT ,1);
  940. bt_plus.affiche(VERT ,1);
  941. bt_SW.affiche(VERT, 1);
  942. bt_FM.affiche(VERT, 1);
  943. bt_AIR.affiche(VERT, 1);
  944. bt_SCN.affiche(VERT, 1);
  945. }
  946.  
  947. bt_4.selected = true;
  948. bt_4.cliked = true;
  949. bt_4.affiche(JAUNE,1);
  950.  
  951. bt_mute.selected = false;
  952. bt_mute.cliked = false;
  953. bt_mute.affiche(ROUGE, 1);
  954. bt_sleep.affiche(VERT, 1);
  955. bt_LED.affiche(VERT, 1);
  956. bt_cal.affiche(VERT, 1);
  957. bt_TEST.affiche(VERT, 1);
  958. bt_reset.affiche(VERT, 1);
  959. bt_quiet.affiche(VERT, 1);
  960. bt_coul.affiche(VERT, 1);
  961.  
  962. affiche_frequence(frequence);
  963.  
  964. valeur_bargraph=0;
  965. if (vu_metre_actif)
  966. {
  967. dessine_VuMetre();
  968. }
  969. else
  970. {
  971. //affi_image_from_SD("/bmp565/montagne170x140.bmp", x0_vu_metre, y0_vu_metre);
  972. }
  973.  
  974.  
  975. TFT.drawRect(0, 0, 319, 240, couleur_traits); // cadre principal pourtour de l'écran
  976. }
  977.  
  978.  
  979. void read_FRQ_File(FS &fs, String filename, String cible) // en mémoire SD
  980. {
  981. Serial.print("Reading file: "); Serial.println(filename);
  982. File file = fs.open(filename);
  983. if (!file ) { Serial.println("failed to open file for reading"); return; }
  984. String s;
  985. uint8_t n =0;
  986.  
  987. while (file.available())
  988. {
  989. char c;
  990. c = char(file.read());
  991. if ((c !='<') && (c !='>')) {s += c;}
  992. if(c=='>')
  993. {
  994. uint32_t frq;
  995. frq = s.toInt();
  996. Serial.println(frq);
  997. s="";
  998. if(cible == "SW") {presetPad1.bt_preset[n].frequence_SW = frq;}
  999. if(cible == "FM") {presetPad1.bt_preset[n].frequence_FM = frq;}
  1000. if(cible == "AIR") {presetPad1.bt_preset[n].frequence_AIR = frq;}
  1001. n++;
  1002. }
  1003. }
  1004. file.close();
  1005. }
  1006.  
  1007.  
  1008. String read_line_params(uint16_t line_num)
  1009. {
  1010. int i = 1;
  1011. char buffer[64];
  1012. String s;
  1013.  
  1014. File file = SD.open("/params.txt", "r");
  1015.  
  1016. while (file.available())
  1017. {
  1018. int l = file.readBytesUntil('\n', buffer, sizeof(buffer));
  1019. buffer[l] = 0;
  1020. if (line_num == i)
  1021. {
  1022. s = buffer;
  1023. file.close();
  1024. return(s);
  1025. }
  1026. i++;
  1027. }
  1028. return "";
  1029. }
  1030.  
  1031.  
  1032. int32_t extract_params(String ligne, String label)
  1033. {
  1034. String s2;
  1035. uint32_t valeur = 0;
  1036. int p1, p2;
  1037.  
  1038. p1 = ligne.indexOf('['); p2 = ligne.indexOf(']');
  1039. s2 = ligne.substring(p1+1, p2);
  1040.  
  1041. if (s2 == label)
  1042. {
  1043. p1 = ligne.indexOf('<'); p2 = ligne.indexOf('>');
  1044. s2 = ligne.substring(p1+1, p2);
  1045. valeur = s2.toInt();
  1046. return valeur;
  1047. }
  1048. return -1;
  1049. }
  1050.  
  1051.  
  1052. void read_params()
  1053. {
  1054. Serial.println("---------------------------------------------");
  1055. // lecture du fichier '/params.txt' en SD
  1056. Serial.println("lecture du fichier '/params.txt' en SD");
  1057. String s1;
  1058. int valeur;
  1059. //Serial.println("read params() ");
  1060.  
  1061. //for(uint8_t n=1; n<=6; n++) // lit toutes(6) lignes du fichier
  1062. s1 = "Z";
  1063. uint8_t n=1;
  1064. while (s1 !="")
  1065. {
  1066. s1 = read_line_params(n); // retourne(par exemple): [couleur_fond]<267>
  1067. Serial.print(n); Serial.println(" " + s1);
  1068.  
  1069. valeur = extract_params(s1, "couleur_fond"); // extrait la valeur correspondant au label
  1070. if(valeur != -1) {couleur_fond_ecran = valeur;}
  1071.  
  1072. //couleur_fond_ecran = VERT_FONCE; // pour TEST
  1073.  
  1074. valeur = extract_params(s1, "frequence");
  1075. if(valeur != -1) {frequence = valeur;}
  1076.  
  1077. valeur = extract_params(s1, "Ax");
  1078. if(valeur != -1) {A.x = valeur;}
  1079.  
  1080. valeur = extract_params(s1, "Ay");
  1081. if(valeur != -1) {A.y = valeur;}
  1082.  
  1083. valeur = extract_params(s1, "Bx");
  1084. if(valeur != -1) {B.x = valeur;}
  1085.  
  1086. valeur = extract_params(s1, "By");
  1087. if(valeur != -1) {B.y = valeur;}
  1088.  
  1089. n++;
  1090. }
  1091. Serial.print("---------------------------------------------");
  1092. }
  1093.  
  1094.  
  1095. void draw_AEC(uint16_t x0, uint16_t y0, uint16_t L, uint8_t sens)
  1096. {
  1097. // ligne arc-en-ciel
  1098. // affiche une ligne de pixels colorés à partir de la variable 'couleurs_aec' mémorisée en PROGMEM (voir fichier Couleurs_AEC.h)
  1099. // L = longueur de la ligne
  1100.  
  1101. //Serial.println("draw_draw_AEC()");
  1102. uint16_t x, i, j;
  1103. uint16_t y1;
  1104. uint16_t couleur_i;
  1105.  
  1106. for (int16_t i=0; i<L; i++)
  1107. {
  1108. float f = 470.0/L * i; // pour balayer toute l'échelle des couleurs disponibles
  1109. j=uint16_t(f);
  1110.  
  1111. couleur_i = couleurs_aec[2*j] | couleurs_aec[2*j+1]<<8;
  1112.  
  1113. if (sens==0){x=i;} else {x=L-i;}
  1114. TFT.drawPixel(x0+x, y0, couleur_i);
  1115. }
  1116. }
  1117.  
  1118.  
  1119.  
  1120. void set_frq_default()
  1121. {
  1122. presetPad1.bt_preset[0].frequence_FM = 88000;
  1123. presetPad1.bt_preset[1].frequence_FM = 90000;
  1124. presetPad1.bt_preset[2].frequence_FM = 92000;
  1125. presetPad1.bt_preset[3].frequence_FM = 94000;
  1126. presetPad1.bt_preset[4].frequence_FM = 96000;
  1127. presetPad1.bt_preset[5].frequence_FM = 100000;
  1128. presetPad1.bt_preset[6].frequence_FM = 104000;
  1129. presetPad1.bt_preset[7].frequence_FM = 108000;
  1130.  
  1131. }
  1132.  
  1133.  
  1134. void setup()
  1135. {
  1136. // étalonnage touch screen; ces valeurs peuvent varier d'un afficheur à l'autre
  1137. // pour l'instant il faut les fixer ici à la main...
  1138. eTS.x0 = -30; eTS.y0 = -30;
  1139. eTS.dx = 11; eTS.dy = 14;
  1140.  
  1141. Serial.begin(115200);
  1142. delay(20);
  1143.  
  1144. pinMode(GPIO_BL, OUTPUT);
  1145. digitalWrite(GPIO_BL, HIGH);
  1146.  
  1147. init_variables_globales();
  1148.  
  1149. Wire.begin(GPIO_SDA, GPIO_SCL, 2000000);
  1150. Tuner_Init(tuner_init_tab9216);
  1151. //affiche_frequence(frequence);
  1152.  
  1153. // Start the SPI for the touch screen and init the TS library
  1154. mySpi.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS);
  1155. ts.begin(mySpi);
  1156. ts.setRotation(3);
  1157.  
  1158. // mySpi2 -> pour le lecteur de SDcard
  1159. // mySpi2 -> partage du bus SPI - mêmes valeurs de GPIO (sck=14, miso=12)
  1160. // que pour l'afficheur ILI9341 , sauf CS=5. Voir sur le schéma ainsi que le fichier User_Setup.h
  1161. mySpi2.begin(14, 12, 13, 5);
  1162.  
  1163. init_SDcard();
  1164. delay(20);
  1165.  
  1166. TFT.init();
  1167. TFT.setRotation(3); // 0..3 à voir, suivant disposition de l'afficheur
  1168. TFT.fillScreen(NOIR);
  1169.  
  1170. if (SDcardOk == false)
  1171. {
  1172. affi_message
  1173. (
  1174. "SDcard absente",
  1175. "Les parametres vont manquer, freq",
  1176. "(freq preset)",
  1177. "couleurs...",
  1178. "calibrage Touch Screen"
  1179. );
  1180. }
  1181.  
  1182. init_sprites();
  1183.  
  1184. affi_image_from_SD("/bmp565/7.bmp", 0, 0); // IMAGE D'ACCEUIL
  1185. delay(500);
  1186.  
  1187. if (SDcardOk == true)
  1188. {
  1189. read_params(); // sur la SDcard
  1190. }
  1191. else
  1192. {
  1193. frequence = 88000;
  1194. }
  1195.  
  1196. // si les coordonnées des points de calibrage sont aux fraises...
  1197. if (abs(A.x-600)>100 || abs(A.y-500)>100 || (abs(B.x-3700)>500 || abs(B.y-3600)>500 ) )
  1198. {
  1199. TS_calibrate();
  1200. }
  1201.  
  1202. groupe_SW.filename = "/FRQ_SW.txt"; // nom du fichier sur la SDcard
  1203. groupe_FM.filename = "/FRQ_FM.txt";
  1204. groupe_AIR.filename = "/FRQ_AIR.txt";
  1205.  
  1206. if (SDcardOk == true)
  1207. {
  1208. load_GRP_FREQ_SD();
  1209. groupe_SCAN.RAZ();
  1210. presetPad1.set_frequences_PRST();
  1211. presetPad1.set_couleurs();
  1212. } // -> to RAM
  1213. else
  1214. {
  1215. set_frq_default();
  1216. }
  1217.  
  1218. init_affichages();
  1219.  
  1220. saut_freq = 100;
  1221.  
  1222. //Tuner_Patch(); // envoi une tartine (6000 bytes) de code, non documentée; Je ne constate aucun effet bénéfique...
  1223. /*
  1224. Le PDF de NXP précise : "Use of these I2C transmissions is required for proper and full function and performance
  1225. as described in this user manual". (une sorte de vaccin anti-Covid donc...)
  1226. Toutefois si quelqu'un a réussi à déchiffrer le truc et peut me donner la liste des fonctions améliorées
  1227. je serais très heureux de le publier ici. Vous avez mon e-mail sur mon site www.silicium628.fr
  1228. */
  1229. //delay(50);
  1230.  
  1231. Tuner_Init(tuner_init_tab9216);
  1232. delay(50);
  1233.  
  1234. // Set_no_AM_gain_reduction();
  1235.  
  1236. bt_mode_FRQ.selected = false;
  1237. bt_mode_MEM.selected = true;
  1238.  
  1239. uint16_t c1 = GRIS_6;
  1240. uint16_t c2 = VERT;
  1241. uint16_t c3 = JAUNE;
  1242. bt_mode_FRQ.affiche(c2, 2); // bt en haut à gauche
  1243. bt_mode_MEM.affiche(c3, 2); // bt en haut à gauche
  1244.  
  1245. groupe_actif = gFM;
  1246. bande_active = FM;
  1247. modulation_active = WFM;
  1248. bt_FM.selected = true;
  1249. bt_SW.selected = false;
  1250. bt_AIR.selected = false;
  1251. bt_SCN.selected = false;
  1252.  
  1253. bt_SW.affiche(c2, 1);
  1254. bt_FM.affiche(c3, 1);
  1255.  
  1256. //clic_logiciel_bouton(&presetPad1.bt_preset[0]);
  1257. //traite_boutons_presetPad(0);
  1258.  
  1259. uint8_t nb_F = groupe_FM.nb_freq;
  1260. affiche_numero_frq(String(1), String(nb_F));
  1261.  
  1262. //couleur_fond_ecran = VERT_FONCE;
  1263.  
  1264. Serial.print("frequence="); Serial.println(frequence);
  1265. affiche_frequence(frequence);
  1266. Tune_Frequence(frequence);
  1267.  
  1268. Set_Volume(+70); // +60
  1269. delay(20);
  1270.  
  1271. //clic_logiciel_bouton(&bt_mode_MEM);
  1272. mode_s = _MEM;
  1273. efface_index_frq();
  1274.  
  1275. if (test_touch_screen == true) {printTouchToDisplay();}
  1276.  
  1277. // TS_calibrate(); pour forcer le calibrage
  1278.  
  1279. Serial.print("- FIN DU SETUP -----------------");
  1280. // FIN DU SETUP
  1281. }
  1282.  
  1283.  
  1284. void get_XY_touch()
  1285. {
  1286. TS_Point p = ts.getPoint();
  1287. float dx = B.x - A.x;
  1288. float ech_x = 300.0 / dx;
  1289. float x0 = A.x;
  1290.  
  1291. float dy = B.y - A.y;
  1292. float ech_y = 220.0 / dy;
  1293. float y0 = A.y;
  1294.  
  1295. memo_x_touch = x_touch;
  1296. memo_y_touch = y_touch;
  1297.  
  1298. x_touch = 10 + uint16_t( (p.x - x0) * ech_x);
  1299. y_touch = 10 + uint16_t( (p.y - y0) * ech_y);
  1300.  
  1301. /*
  1302. TFT.pushRect(memo_x_touch, memo_y_touch-10, 1, 20, memo_tiret_V); // efface avec l'image enregistrée
  1303. TFT.pushRect(memo_x_touch-10, memo_y_touch, 20, 1, memo_tiret_H); // efface avec l'image enregistrée
  1304.  
  1305. TFT.readRect(x_touch, y_touch-10, 1, 20, memo_tiret_V); // mémorise le segment avant de tracer
  1306. TFT.readRect(x_touch-10, y_touch, 20, 1, memo_tiret_H); // mémorise le segment avant de tracerfloat sy = sin((i - 90) * deg_to_rad);
  1307.  
  1308. TFT.drawFastVLine(x_touch, y_touch-10, 20, NOIR); // tiret vertical
  1309. TFT.drawFastHLine(x_touch-10, y_touch, 20, NOIR); // tiret horizontal
  1310. */
  1311.  
  1312. }
  1313.  
  1314.  
  1315. void printTouchToDisplay() // pour TEST
  1316. {
  1317. TFT.fillScreen(NOIR);
  1318.  
  1319. TFT.setFreeFont(FM9);
  1320. TFT.setTextColor(BLEU_CLAIR, NOIR);
  1321. TFT.drawString("TEST TOUCH screen", 80, 120);
  1322.  
  1323. while(1)
  1324. {
  1325. if (ts.tirqTouched() && ts.touched())
  1326. {
  1327. get_XY_touch();
  1328. TFT.drawRect(x_touch, y_touch, 1, 1, JAUNE);
  1329. }
  1330. }
  1331. }
  1332.  
  1333.  
  1334. // -------------------------------------------------------------------------
  1335. // Le vu-metre est une variante perso du code : "/Arduino/libraries/TFT_eSPI/examples/480 x 320/TFT_Meters"
  1336. // voir le fichier licence.txt dans le dossier "/Arduino/libraries/TFT_eSPI/examples/"
  1337. void dessine_VuMetre()
  1338. {
  1339. if (vu_metre_actif == false) {return;}
  1340.  
  1341. uint16_t x0 = x0_vu_metre;
  1342. uint16_t y0 = y0_vu_metre;
  1343.  
  1344. uint16_t dx=140;
  1345. uint16_t dy=70;
  1346.  
  1347. uint8_t AA = 65; // 65
  1348. uint8_t BB = x0 +dx/2;// 120
  1349. uint8_t CC = y0 + dy+20; // 140
  1350.  
  1351. TFT.setFreeFont(FF0);
  1352. // cadre rectangulaire
  1353. TFT.fillRect(x0, y0, dx, dy, GRIS_3);
  1354. TFT.fillRect(x0+3, y0+3, dx-6, dy-6, BLANC);
  1355.  
  1356. TFT.setTextColor(NOIR);
  1357.  
  1358. // graduation chaque 5 deg entre -50 et +50 deg
  1359. for (int i = -50; i < 51; i += 10)
  1360. {
  1361. int tl = 5; // tiret plus long
  1362. // Coordonnées du tiret à dessiner
  1363. float sx = cos((i - 90) * deg_to_rad);
  1364. float sy = sin((i - 90) * deg_to_rad);
  1365. uint16_t tx0 = sx * (AA + tl) + BB;
  1366. uint16_t ty0 = sy * (AA + tl) + CC;
  1367. uint16_t tx1 = sx * AA + BB;
  1368. uint16_t ty1 = sy * AA + CC;
  1369.  
  1370. float sx2 = cos((i + 5 - 90) * deg_to_rad);
  1371. float sy2 = sin((i + 5 - 90) * deg_to_rad);
  1372. int tx2 = sx2 * (AA + tl) + BB;
  1373. int ty2 = sy2 * (AA + tl) + CC;
  1374. int tx3 = sx2 * AA + BB;
  1375. int ty3 = sy2 * AA + CC;
  1376.  
  1377. // zone verte
  1378. if (i >= 0 && i < 25)
  1379. {
  1380. TFT.fillTriangle(tx0, ty0, tx1, ty1, tx2, ty2, VERT);
  1381. TFT.fillTriangle(tx1, ty1, tx2, ty2, tx3, ty3, VERT);
  1382. }
  1383.  
  1384. // zone orange
  1385. if (i >= 25 && i < 50)
  1386. {
  1387. TFT.fillTriangle(tx0, ty0, tx1, ty1, tx2, ty2, ORANGE);
  1388. TFT.fillTriangle(tx1, ty1, tx2, ty2, tx3, ty3, ORANGE);
  1389. }
  1390.  
  1391. if (i % 25 != 0) tl = 8;
  1392.  
  1393. tx0 = sx * (AA + tl) + BB;
  1394. ty0 = sy * (AA + tl) + CC;
  1395. tx1 = sx * AA + BB;
  1396. ty1 = sy * AA + CC;
  1397.  
  1398. TFT.drawLine(tx0, ty0, tx1, ty1, NOIR);
  1399.  
  1400. if (i % 20 == 0)
  1401. {
  1402. tx0 = sx * (AA + tl + 10) + BB;
  1403. ty0 = sy * (AA + tl + 10) + CC;
  1404. switch (i / 20)
  1405. {
  1406. case -2: TFT.drawCentreString("0", tx0, ty0 - 6, 1); break;
  1407. case -1: TFT.drawCentreString("25", tx0, ty0 - 4, 1); break;
  1408. case 0: TFT.drawCentreString("50", tx0, ty0 - 6, 1); break;
  1409. case 1: TFT.drawCentreString("75", tx0, ty0 - 4, 1); break;
  1410. case 2: TFT.drawCentreString("100", tx0, ty0 - 6, 1); break;
  1411. }
  1412. }
  1413. sx = cos((i + 5 - 90) * deg_to_rad);
  1414. sy = sin((i + 5 - 90) * deg_to_rad);
  1415. tx0 = sx * AA + BB;
  1416. ty0 = sy * AA + CC;
  1417. if (i < 50) {TFT.drawLine(tx0, ty0, tx1, ty1, NOIR);}
  1418. }
  1419. }
  1420.  
  1421.  
  1422.  
  1423. void plotAiguille(float value)
  1424. {
  1425. if (vu_metre_actif == false) {return;}
  1426.  
  1427. uint16_t x0 = x0_vu_metre;
  1428. uint16_t y0 = y0_vu_metre;
  1429. uint16_t dx=140;
  1430. uint16_t dy=50;
  1431.  
  1432. uint8_t AA = dx/2; // 100
  1433. uint8_t BB = x0 +dx/2;// 120
  1434. uint8_t CC = y0 + dy+25; // 140
  1435.  
  1436. TFT.setTextColor(TFT_BLACK, BLANC);
  1437. char buf[8]; dtostrf(value, 4, 0, buf);
  1438.  
  1439. if (value < -10) value = -10;
  1440. if (value > 110) value = 110;
  1441.  
  1442. float sdeg = map(value, -10, 110, -150, -30);
  1443. float sx = cos(sdeg * deg_to_rad);
  1444. float sy = sin(sdeg * deg_to_rad);
  1445.  
  1446. float tx = tan((sdeg + 90) * deg_to_rad);
  1447.  
  1448. TFT.drawLine(BB + 20*ltx - 1, CC - 20, osx - 1, osy, BLANC); //efface
  1449. TFT.drawLine(BB + 20*ltx, CC - 20, osx, osy, BLANC);
  1450. TFT.drawLine(BB + 20*ltx + 1, CC - 20, osx + 1, osy, BLANC);
  1451.  
  1452. ltx = tx;
  1453. osx = sx*50 + BB;
  1454. osy = sy*50 + CC;
  1455.  
  1456. TFT.drawLine(BB + 20*ltx - 1, CC - 20, osx - 1, osy, ROUGE);
  1457. TFT.drawLine(BB + 20*ltx, CC - 20, osx, osy, VIOLET);
  1458. TFT.drawLine(BB + 20*ltx + 1, CC - 20, osx + 1, osy, ROUGE);
  1459.  
  1460. TFT.fillRect(x0, y0+dy+5, dx, 15, GRIS_2);
  1461. }
  1462.  
  1463.  
  1464.  
  1465. void init_box_info() // en bas à gauche
  1466. {
  1467. TFT.fillRect(x0_box_info1+1, y0_box_info1+1, 118, 16, NOIR); // efface
  1468. TFT.setFreeFont(FF0);
  1469. TFT.setTextColor(JAUNE, couleur_fond_ecran);
  1470. //TFT.drawString("RDS", x0_box_info1 -20, y0_box_info1 + 4);
  1471. }
  1472.  
  1473.  
  1474. void affiche_unit(String s)
  1475. {
  1476. TFT.setTextColor(JAUNE, NOIR);
  1477. TFT.setFreeFont(FM9); //FM9 FMB9 FSS9... voir le fichier FrSD_Fonts.h
  1478. TFT.drawString(s, FRQ_x0 + 225, FRQ_y0 + 35);
  1479. }
  1480.  
  1481.  
  1482. void efface_numero_frq()
  1483. {
  1484. TFT.fillRect(FRQ_x0 + 225, FRQ_y0 + 20, 40, 12, couleur_fond_ecran);
  1485. }
  1486.  
  1487.  
  1488. void affiche_numero_frq(String s1, String s2)
  1489. {
  1490. //TFT.fillRect(FRQ_x0 + 225, FRQ_y0 + 5, 10, 10, BLEU);
  1491. TFT.setTextColor(BLANC, couleur_fond_ecran);
  1492. TFT.setFreeFont(FF0);
  1493. TFT.drawString(s1 + "/" + s2 + " ", FRQ_x0 + 225, FRQ_y0 + 20);
  1494. affiche_box_FRQ(GRIS_3); // pour retracer le côté droit du rectangle
  1495. }
  1496.  
  1497.  
  1498. void affiche_band(String s) // à droite des gros chiffres
  1499. {
  1500. //TFT.fillRect(FRQ_x0 + 225, FRQ_y0 + 5, 10, 10, BLEU);
  1501. TFT.setTextColor(BLANC, NOIR);
  1502. TFT.setFreeFont(FM9);
  1503. String blancs;
  1504. if (s == "AIR") {blancs = " ";} else {blancs = " ";}
  1505.  
  1506. TFT.drawString(s + blancs, FRQ_x0 + 225, FRQ_y0);
  1507. affiche_box_FRQ(GRIS_3); // pour retracer le côté droit du rectangle
  1508. }
  1509.  
  1510.  
  1511. void efface_box_entete1() // tout en haut à gauche
  1512. {
  1513. TFT.fillRect(1, 1, 50, 12, NOIR);
  1514. TFT.drawFastVLine(50, 0, 12, BLANC);
  1515. }
  1516.  
  1517.  
  1518. void efface_box_entete2() // tout en haut au centre
  1519. {
  1520. TFT.fillRect(50, 1, 180, 12, NOIR);
  1521. TFT.drawFastVLine(50, 0, 12, BLANC);
  1522. TFT.drawFastVLine(230, 0, 12, BLANC);
  1523. }
  1524.  
  1525.  
  1526. void efface_box_entete3() // tout en haut à droite
  1527. {
  1528. TFT.fillRect(230, 1, 89, 12, BLEU);
  1529. TFT.drawFastVLine(230, 0, 12, BLANC);
  1530. memo_valeur_affi--; // pour réafficher tension batterie
  1531. }
  1532.  
  1533.  
  1534. void affiche_box_FRQ(uint16_t couleur) // autour de la fréquence (en gros chiffres JAUNE
  1535. {
  1536. TFT.drawRect(0, FRQ_y0 -17, 319, 74, couleur);
  1537. }
  1538.  
  1539.  
  1540. void affiche_box_presets() // boutons 1 2 3 4 5 6 7 8
  1541. {
  1542. TFT.fillRect(x0_box_PRESET, y0_box_PRESET, 164, 24, NOIR);
  1543. TFT.setTextColor(GRIS_3, NOIR);
  1544.  
  1545. }
  1546.  
  1547.  
  1548. void affiche_box_GROUPE() // groupes de fréquences; contient 4 boutons SW, FM, AIR, SC
  1549. {
  1550. TFT.fillRect(x0_box_GROUPE, y0_box_GROUPE, 105, 23, NOIR);
  1551. //TFT.drawRect(x0_box_GROUPE, y0_box_GROUPE, 105, 25, couleur_traits);
  1552. TFT.setFreeFont(FF0);
  1553. TFT.setTextColor(GRIS_3, NOIR);
  1554. TFT.drawString("groupes Freq", x0_box_GROUPE+4, y0_box_GROUPE-6);
  1555. }
  1556.  
  1557.  
  1558. void efface_box_GROUPE()
  1559. {
  1560. //TFT.fillRect(x0_box_GROUPE, y0_box_GROUPE-7, 110, 33, couleur_fond_ecran);
  1561. //TFT.fillRect(x0_box_SCAN, y0_box_SCAN, dx_box_SCAN, dy_box_SCAN, NOIR);
  1562. }
  1563.  
  1564.  
  1565. void affiche_box_SD() // Raz, Write, Raz 1F, LST
  1566. {
  1567. TFT.fillRect(x0_box_SD, y0_box_SD + 10, 46, 58, NOIR);
  1568. TFT.setFreeFont(FF0);
  1569. TFT.setTextColor(GRIS_3, NOIR);
  1570. TFT.drawString("SD", x0_box_SD+6, y0_box_SD+6);
  1571. }
  1572.  
  1573.  
  1574. void affiche_box_scan(uint16_t dy)
  1575. {
  1576. init_1_bouton_rouge(1, 295, y0_box_SCAN+1, 20, 20, "x", &bt_stop_scan);
  1577. if (bande_active != AIR)
  1578. {
  1579. init_1_bouton(1, 275, y0_box_SCAN+40, 40, 15, "rescan", &bt_re_scan);
  1580. init_1_bouton(1, 275, y0_box_SCAN+58, 40, 14, " >>", &bt_scan_suivant);
  1581. }
  1582. init_1_bouton(1, 255, y0_box_SCAN+1, 25, 15, "+", &bt_seuil_plus);
  1583. init_1_bouton(1, 255, y0_box_SCAN+20, 25, 15, "-", &bt_seuil_moins);
  1584. init_1_bouton(1, 4, y0_box_SCAN+3, 15, 15, "L", &bt_LEV);
  1585. init_1_bouton(1, 4, y0_box_SCAN+20, 15, 15, "N", &bt_SNR);
  1586. }
  1587.  
  1588.  
  1589. void affi_boutons_SW_FM_AIR_SCN()
  1590. {
  1591. if((mode_affi == SCAN_F ) || (mode_affi == SCAN_M )) {return;}
  1592.  
  1593. uint16_t c1 = GRIS_5;
  1594. uint16_t c2 = VERT;
  1595. bt_SW.affiche(c2, 1);
  1596. bt_FM.affiche(c2, 1);
  1597. bt_AIR.affiche(c2, 1);
  1598. bt_SCN.affiche(BLEU_CLAIR, 1);
  1599. bt_mute.affiche(ROUGE, 1);
  1600.  
  1601. }
  1602.  
  1603.  
  1604. void affiche_frequence(uint32_t frq)
  1605. {
  1606. Serial.println("affiche_frequence()");
  1607.  
  1608. TFT.fillRect(x0_box_info1+2, y0_box_info1, 118, 16, NOIR); // efface (en bas à gauche)
  1609.  
  1610. uint16_t couleur_chiffres;
  1611.  
  1612. if(mode_s == _FRQ) {couleur_chiffres = VERT_chiffres;}
  1613. if(mode_s == _MEM) {couleur_chiffres = JAUNE_chiffres;}
  1614.  
  1615. if(bande_SW) // d'après la fréquence; SW - 28 MHz = limite haute du module
  1616. {
  1617. affiche_band("SW");
  1618.  
  1619. modulation_active = AM;
  1620. if (groupe_actif != gSCN) {bande_active = SW; groupe_actif == gSW;}
  1621. bt_SW.selected = true;
  1622. bt_FM.selected = false; // les boutons sont exclusifs
  1623. bt_AIR.selected = false;
  1624. bt_SCN.selected = false;
  1625. affi_boutons_SW_FM_AIR_SCN();
  1626.  
  1627. String s1, sM, sK;
  1628. uint8_t L;
  1629.  
  1630. s1 = String(frq);
  1631. s1 = "000000" + s1;
  1632. L= s1.length();
  1633.  
  1634. sK = s1.substring(L-3); // kHz
  1635. sM = s1.substring(L-6, L-3); // Mhz
  1636.  
  1637. sprite_frq.fillRect(0, 0, 220, 60, NOIR); // efface
  1638.  
  1639. sprite_frq.setTextColor(couleur_chiffres, NOIR);
  1640. sprite_frq.drawString(sM + "." + sK + " ", 220+10, 32);
  1641. // remarque: le fait d'ajouter " " à la fin évite aux chiffres de se balader horizontalement !
  1642. sprite_frq.pushSprite(FRQ_x0, FRQ_y0);
  1643. affiche_unit("MHz");
  1644. Tune_Frequence(frq);
  1645. }
  1646.  
  1647. else if(bande_FM) // bande FM, on efface les deux '0' de droite (si == 0 sinon on affiche quand même)
  1648. {
  1649. affiche_band("FM");
  1650. modulation_active = WFM;
  1651. if (groupe_actif != gSCN) {bande_active = FM; groupe_actif == gFM;}
  1652.  
  1653. affi_boutons_SW_FM_AIR_SCN();
  1654.  
  1655. String s1, sM, sK1, sK2, sK3;
  1656. String decimales;
  1657. uint8_t x0 = 0;
  1658. uint8_t L;
  1659.  
  1660. s1 = String(frq);
  1661. s1 = "000000" + s1;
  1662. L= s1.length();
  1663.  
  1664. sK1 = s1.substring(L-3, L-2); // 1ere décimale
  1665. sK2 = s1.substring(L-2, L-1); // 2eme décimale
  1666. sK3 = s1.substring(L-1, L); // 3eme décimale
  1667.  
  1668. if ((sK2 == "0") && (sK3 == "0"))
  1669. {
  1670. decimales = sK1;
  1671. x0=170;
  1672. }
  1673. else
  1674. {
  1675. decimales = sK1 + sK2 + sK3;
  1676. x0=232;
  1677. }
  1678.  
  1679. if (frq < 100000) {sM = s1.substring(L-5, L-3); }// on ne retient que deux chiffres à gauche du point
  1680. else { sM = s1.substring(L-6, L-3); } // on garde 3 chiffres à gauche du point décimal
  1681.  
  1682. sprite_frq.fillRect(0, 0, 220, 60, NOIR); // efface
  1683. sprite_frq.setTextColor(couleur_chiffres, NOIR);
  1684. sprite_frq.drawString(sM + "." + decimales + " ", x0, 32);
  1685. // remarque: le fait d'ajouter " " à la fin évite aux chiffres de se balader horizontalement !
  1686. sprite_frq.pushSprite(FRQ_x0, FRQ_y0);
  1687. affiche_unit("MHz");
  1688.  
  1689. Tune_Frequence(frq);
  1690. bt_mute.selected = false;
  1691. bt_mute.cliked = false;
  1692.  
  1693. }
  1694.  
  1695. else if(bande_AIR) // bande AIR - 138000-110000 = 28MHz (limite haute de réception AM du module)
  1696. {
  1697. affiche_band("AIR");
  1698. modulation_active = AM;
  1699. if (groupe_actif != gSCN) {bande_active = AIR; groupe_actif == gAIR;}
  1700.  
  1701. bt_AIR.selected = true;
  1702. bt_SW.selected = false; // les boutons sont exclusifs
  1703. bt_FM.selected = false;
  1704. bt_SCN.selected = false;
  1705. affi_boutons_SW_FM_AIR_SCN();
  1706.  
  1707. String s1, sM, sK;
  1708. uint8_t L;
  1709.  
  1710. s1 = String(frq);
  1711. s1 = "000000" + s1;
  1712. L= s1.length();
  1713.  
  1714. sK = s1.substring(L-3); // kHz
  1715. sM = s1.substring(L-6, L-3); // Mhz
  1716.  
  1717. sprite_frq.fillRect(0, 0, 220, 60, NOIR); // efface
  1718. sprite_frq.setTextColor(couleur_chiffres, NOIR);
  1719. sprite_frq.drawString(sM + "." + sK + " ", 220+10, 32);
  1720. sprite_frq.pushSprite(FRQ_x0, FRQ_y0);
  1721. affiche_unit("MHz");
  1722. Tune_Frequence(frq);
  1723. }
  1724.  
  1725. else if(bande_interdite1 || bande_interdite2) // bandes interdites par le module TEF6686
  1726. {
  1727. affiche_band("---");
  1728. TFT.setTextColor(ROUGE, NOIR);
  1729. TFT.setFreeFont(FF0);
  1730. TFT.drawString("FRQ non disponible", 80, 2);
  1731. //delay(2000);
  1732.  
  1733. String s1, sM, sK;
  1734. uint8_t L;
  1735.  
  1736. s1 = String(frq);
  1737. s1 = "000000" + s1;
  1738. L= s1.length();
  1739.  
  1740. sK = s1.substring(L-3); // kHz
  1741. sM = s1.substring(L-6, L-3); // Mhz
  1742.  
  1743. sprite_frq.fillRect(0, 0, 220, 60, NOIR); // efface
  1744. sprite_frq.setTextColor(GRIS_1, NOIR);
  1745. sprite_frq.drawString(sM + "." + sK + " ", 220+10, 32);
  1746. // remarque: le fait d'ajouter " " à la fin évite aux chiffres de se balader horizontalement !
  1747. sprite_frq.pushSprite(FRQ_x0, FRQ_y0);
  1748. affiche_unit("MHz");
  1749.  
  1750. bt_mute.selected = true;
  1751. bt_mute.affiche(ROUGE, 1);
  1752. bt_mute.selected = false;
  1753. mute = true;
  1754. Set_Mute(mute); // fonction située dans le fichier 'driverTEF6686_628.h'
  1755.  
  1756. }
  1757. else
  1758. {
  1759. affiche_band("---");
  1760. TFT.setTextColor(ROUGE, NOIR);
  1761. TFT.setFreeFont(FF0);
  1762. TFT.drawString("FRQ non disponible", 80, 2);
  1763. //delay(2000);
  1764.  
  1765. String s1, sM, sK;
  1766. uint8_t L;
  1767.  
  1768. s1 = String(frq);
  1769. s1 = "000000" + s1;
  1770. L= s1.length();
  1771.  
  1772. sK = s1.substring(L-3); // kHz
  1773. sM = s1.substring(L-6, L-3); // Mhz
  1774.  
  1775. sprite_frq.fillRect(0, 0, 220, 60, NOIR); // efface
  1776. sprite_frq.setTextColor(GRIS_1, NOIR);
  1777. sprite_frq.drawString(sM + "." + sK + " ", 220+10, 32);
  1778. // remarque: le fait d'ajouter " " à la fin évite aux chiffres de se balader horizontalement !
  1779. sprite_frq.pushSprite(FRQ_x0, FRQ_y0);
  1780. affiche_unit("MHz");
  1781.  
  1782. bt_mute.selected = true;
  1783. bt_mute.affiche(ROUGE, 1);
  1784. bt_mute.selected = false;
  1785. mute = true;
  1786. Set_Mute(mute); // fonction située dans le fichier 'driverTEF6686_628.h
  1787. }
  1788.  
  1789. if(frq==138000) { affiche_band("max"); }
  1790. if(frq>138000) { affiche_band("---"); }
  1791. }
  1792.  
  1793.  
  1794. void clic_logiciel_bouton(TOUCH_BOUTON *bouton_i)
  1795. {
  1796. uint16_t c1 = NOIR;
  1797. uint16_t c2 = JAUNE;
  1798.  
  1799. bouton_i->cliked = true;
  1800. bouton_i->selected = true;
  1801. bouton_i->affiche(c2, 1);
  1802. }
  1803.  
  1804.  
  1805.  
  1806. void test_clic_boutons(TOUCH_BOUTON *bouton_i)
  1807. {
  1808. uint16_t c1 = NOIR;
  1809. uint16_t c2 = GRIS_2;
  1810.  
  1811. if ((x_touch > bouton_i->x0) && (x_touch < (bouton_i->x0 )+ bouton_i->read_dx())
  1812. && ( y_touch > ((bouton_i->y0) -5) ) && (y_touch < ((bouton_i->y0) + (bouton_i->read_dy())+5) ) )
  1813. {
  1814. bouton_i->cliked = true;
  1815. bouton_i->selected = true;
  1816. bouton_i->affiche(c2, 1);
  1817. delay(100);
  1818. }
  1819. }
  1820.  
  1821.  
  1822.  
  1823. void test_clic_6_boutons_frq() // 6 rectangles situés au dessus des gros chiffres de la fréquence
  1824. {
  1825. uint16_t c1 = NOIR;
  1826. uint16_t c2 = VERT;
  1827.  
  1828. if (( y_touch > (bt_1.y0-20)) && (y_touch < (bt_1.y0 + bt_1.read_dy()+20)) ) // zone des 6 boutons au dessus de la fréquence
  1829. {
  1830. bt_1.cliked = false; bt_1.selected = false; test_clic_boutons(&bt_1 ); bt_1.affiche(c2,1);
  1831. bt_2.cliked = false; bt_2.selected = false; test_clic_boutons(&bt_2 ); bt_2.affiche(c2,1);
  1832. bt_3.cliked = false; bt_3.selected = false; test_clic_boutons(&bt_3 ); bt_3.affiche(c2,1);
  1833. bt_4.cliked = false; bt_4.selected = false; test_clic_boutons(&bt_4 ); bt_4.affiche(c2,1);
  1834. bt_5.cliked = false; bt_5.selected = false; test_clic_boutons(&bt_5 ); bt_5.affiche(c2,1);
  1835. bt_6.cliked = false; bt_6.selected = false; test_clic_boutons(&bt_6 ); bt_6.affiche(c2,1);
  1836.  
  1837. if (bt_6.cliked) {saut_freq = 1;}
  1838. if (bt_5.cliked) {saut_freq = 10;}
  1839. if (bt_4.cliked) {saut_freq = 100;}
  1840. if (bt_3.cliked) {saut_freq = 1000;}
  1841. if (bt_2.cliked) {saut_freq = 10000;}
  1842. if (bt_1.cliked) {saut_freq = 100000;}
  1843.  
  1844. delay(10);
  1845. }
  1846. }
  1847.  
  1848.  
  1849. void affiche_saisie(String s1)
  1850. {
  1851. efface_box_entete1();
  1852. TFT.setFreeFont(FF0); TFT.setTextColor(VERT, NOIR);
  1853. TFT.drawString(s1, x0_saisie+2, y0_saisie);
  1854. }
  1855.  
  1856.  
  1857. void traite_touches_pad(uint8_t num_touche) // pavé numérique
  1858. {
  1859. if(num_touche == 253) {return;}
  1860.  
  1861. uint16_t c1 = GRIS_6;
  1862. uint16_t c2 = JAUNE;
  1863. uint16_t c3 = VERT;
  1864.  
  1865. int p1;
  1866.  
  1867. if (num_touche == 254) // bouton "."
  1868. {
  1869. frequence_txt += ".";
  1870. affiche_saisie(frequence_txt);
  1871. }
  1872.  
  1873. if (num_touche < 10)
  1874. {
  1875. frequence_txt += String(num_touche);
  1876. affiche_saisie(frequence_txt);
  1877. delay(300);
  1878. }
  1879.  
  1880. x_touch =0;
  1881. y_touch =0;
  1882.  
  1883. if (num_touche == 255) // bouton "ok"
  1884. {
  1885. Serial.println("touche ok");
  1886.  
  1887. efface_box_entete1();
  1888. efface_box_entete2();
  1889. //affiche_saisie(""); // efface
  1890.  
  1891. mode_s = _FRQ;
  1892. bt_mode_MEM.selected = false;
  1893. bt_mode_FRQ.selected = true;
  1894.  
  1895. bt_mode_MEM.affiche(c2, 2);
  1896. bt_mode_FRQ.affiche(c3, 2);
  1897.  
  1898. double F = frequence_txt.toDouble();
  1899. p1 = frequence_txt.indexOf(".");
  1900. if (p1 != -1) {F *=1000;} // si présence du point décimal
  1901.  
  1902. frequence = F;
  1903. affiche_frequence(frequence); // 'Tune_Frequence(frq)' est appelée dans cette fonction 'affiche_frequence()'
  1904.  
  1905. n_appui = 0;
  1906. frequence_txt = "";
  1907. n_appui = 0;
  1908.  
  1909. }
  1910. num_touche = 0;
  1911. }
  1912.  
  1913.  
  1914. void write_fichier_params() // sur la SDcard
  1915. {
  1916. Serial.println("write fichier '/params.txt'");
  1917.  
  1918. File file1 = SD.open("/params.txt", FILE_WRITE);
  1919. String s1;
  1920.  
  1921. s1 ="[couleur_fond]";
  1922. s1 += "<";
  1923. s1 += String(couleur_fond_ecran);
  1924. s1 +=">";
  1925. file1.println(s1);
  1926.  
  1927. s1 ="[frequence]";
  1928. s1 += "<";
  1929. s1 += String(frequence);
  1930. s1 +=">";
  1931. file1.println(s1);
  1932.  
  1933. s1 ="[Ax]";
  1934. s1 += "<";
  1935. s1 += String(A.x);
  1936. s1 +=">";
  1937. file1.println(s1);
  1938.  
  1939. s1 ="[Ay]";
  1940. s1 += "<";
  1941. s1 += String(A.y);
  1942. s1 +=">";
  1943. file1.println(s1);
  1944.  
  1945. s1 ="[Bx]";
  1946. s1 += "<";
  1947. s1 += String(B.x);
  1948. s1 +=">";
  1949. file1.println(s1);
  1950.  
  1951. s1 ="[By]";
  1952. s1 += "<";
  1953. s1 += String(B.y);
  1954. s1 +=">";
  1955. file1.println(s1);
  1956.  
  1957.  
  1958. file1.close();
  1959. delay(100);
  1960. }
  1961.  
  1962.  
  1963. void record_fichier_FRQ_SW_PRST()
  1964. {
  1965. Serial.println("record_fichier_FRQ_SW_PRST()");
  1966.  
  1967. File file1 = SD.open("FRQ_FM_PRST.txt", FILE_WRITE);
  1968. String s1;
  1969.  
  1970. for(uint8_t n=0; n<8; n++)
  1971. {
  1972. s1 = "<";
  1973. s1 += String(presetPad1.bt_preset[n].frequence_SW);
  1974. s1 +=">";
  1975. file1.println(s1);
  1976. }
  1977.  
  1978. file1.close();
  1979. }
  1980.  
  1981.  
  1982.  
  1983. void record_fichier_FRQ_FM_PRST()
  1984. {
  1985. Serial.println("record_fichier_FRQ_FM_PRST()");
  1986.  
  1987. File file1 = SD.open("FRQ_FM_PRST.txt", FILE_WRITE);
  1988. String s1;
  1989.  
  1990. for(uint8_t n=0; n<8; n++)
  1991. {
  1992. s1 = "<";
  1993. s1 += String(presetPad1.bt_preset[n].frequence_FM);
  1994. s1 +=">";
  1995. file1.println(s1);
  1996. }
  1997. file1.close();
  1998. }
  1999.  
  2000.  
  2001. void record_fichier_FRQ_AIR_PRST()
  2002. {
  2003. Serial.println("record_fichier_FRQ_AIR_PRST()");
  2004.  
  2005. File file1 = SD.open("FRQ_AIR_PRST.txt", FILE_WRITE);
  2006. String s1;
  2007.  
  2008. for(uint8_t n=0; n<8; n++)
  2009. {
  2010. s1 = "<";
  2011. s1 += String(presetPad1.bt_preset[n].frequence_AIR);
  2012. s1 +=">";
  2013. file1.println(s1);
  2014. }
  2015. file1.close();
  2016. }
  2017.  
  2018.  
  2019. void traite_boutons_presetPad(uint8_t n_bt)
  2020. {
  2021. if (n_bt > 7) {return;}
  2022.  
  2023. uint16_t c1 = GRIS_5;
  2024. uint16_t c2 = JAUNE;
  2025. uint32_t adr0, adr1, adr2, adr;
  2026.  
  2027. if (mode_affi == NORMAL)
  2028. {
  2029. if(bande_active == SCN)
  2030. {
  2031. bande_active = FM; // afin de pouvoir traiter les fréquences preset attribuées aux boutons
  2032. groupe_actif = gFM;
  2033. modulation_active = WFM;
  2034. bt_FM.selected = true;
  2035. bt_SW.selected = false;
  2036. bt_AIR.selected = false;
  2037. bt_SCN.selected = false;
  2038. affi_boutons_SW_FM_AIR_SCN();
  2039. }
  2040. efface_index_frq();
  2041. mode_s = _MEM;
  2042. bt_mode_MEM.selected = true;
  2043. bt_mode_FRQ.selected = false;
  2044. bt_mode_MEM.affiche(c2, 2);
  2045. bt_mode_FRQ.affiche(c2, 2);
  2046. affiche_frequence(frequence);
  2047.  
  2048. // Lit la frequence dans le bouton concerné (VOIR: 'class TOUCH_BOUTON_PRESET')
  2049. if(bande_active == SW) {frequence = presetPad1.bt_preset[n_bt].frequence_SW;}
  2050. if(bande_active == FM) {frequence = presetPad1.bt_preset[n_bt].frequence_FM;}
  2051. if(bande_active == AIR) {frequence = presetPad1.bt_preset[n_bt].frequence_AIR;}
  2052. }
  2053.  
  2054. if (mode_affi == SET_F_PRESET)
  2055. {
  2056. if(bande_active == SW)
  2057. {
  2058. presetPad1.bt_preset[n_bt].frequence_SW = frequence; // en RAM
  2059. record_fichier_FRQ_SW_PRST();
  2060. mode_affi = NORMAL;
  2061. delay(100);
  2062. }
  2063. if(bande_active == FM)
  2064. {
  2065. presetPad1.bt_preset[n_bt].frequence_FM = frequence;
  2066. record_fichier_FRQ_FM_PRST();
  2067. mode_affi = NORMAL;
  2068. delay(100);
  2069. }
  2070. if(bande_active == AIR)
  2071. {
  2072. presetPad1.bt_preset[n_bt].frequence_AIR = frequence;
  2073. record_fichier_FRQ_AIR_PRST();
  2074. mode_affi = NORMAL;
  2075. delay(100);
  2076. }
  2077.  
  2078. mode_affi = NORMAL;
  2079. vu_metre_actif = true;
  2080. init_affichages();
  2081. }
  2082.  
  2083. vu_metre_actif = true;
  2084. dessine_VuMetre();
  2085. affiche_frequence(frequence);
  2086. TFT.setTextColor(JAUNE, NOIR);
  2087. TFT.setFreeFont(FF0);
  2088. Tune_Frequence(frequence);
  2089. write_fichier_params();
  2090. }
  2091.  
  2092.  
  2093.  
  2094. uint32_t inc_Frq_in_groupe(GROUPE_FREQUENCES *groupe_Freq, int8_t di) // di = +/-1
  2095. {
  2096. if ((di<-1)||(di>1)) {return 0;}
  2097.  
  2098. uint16_t n_max = groupe_Freq->nb_freq;
  2099.  
  2100. uint16_t n = groupe_Freq->num_F_actuelle;
  2101.  
  2102. if(n_max > 99) {n_max = 99;}
  2103.  
  2104. if (di == 1)
  2105. {
  2106. if (n<n_max-1) { n++; }
  2107. else if (n >= (n_max-1)) {n=0;}
  2108. }
  2109.  
  2110. if (di == -1)
  2111. {
  2112. if (n>=1) { n--; }
  2113. else if (n==0) {n = n_max-1;}
  2114. }
  2115.  
  2116. if(n > 99) {n = 0;}
  2117.  
  2118. groupe_Freq->num_F_actuelle = n;
  2119. uint16_t adr = groupe_Freq->adr_1ere_frq + n;
  2120.  
  2121. uint8_t nb_F = groupe_Freq->nb_freq;
  2122. uint8_t num_1ere_F = groupe_Freq->adr_1ere_frq;
  2123. affiche_numero_frq(String(1 + adr - num_1ere_F), String(nb_F));
  2124.  
  2125. uint32_t valeur_lue = groupe_Freq->G_freq[adr];
  2126. return valeur_lue;
  2127.  
  2128. }
  2129.  
  2130.  
  2131.  
  2132. void test_clic_boutons_plus_moins()
  2133. {
  2134. uint16_t c1 = GRIS_6;
  2135. uint16_t c2 = GRIS_3;
  2136.  
  2137. boolean bouton_cliked = false;
  2138.  
  2139. //--------------------------------------------------------------------
  2140. if(mode_s == _FRQ) // on va modifier directement la fréquence
  2141. {
  2142. test_clic_boutons(&bt_plus );
  2143. bt_plus.affiche(c2, 1);
  2144. if (bt_plus.cliked)
  2145. {
  2146. efface_box_entete2();
  2147. presetPad1.deselect_boutons();
  2148. frequence += saut_freq;
  2149. bouton_cliked = true;
  2150. }
  2151.  
  2152. delay(100);
  2153. if (bt_plus.cliked && ((frequence + saut_freq) <= 138000 ))
  2154. {
  2155. Tune_Frequence(frequence);
  2156. }
  2157.  
  2158. bt_plus.cliked = false;
  2159. bt_plus.selected = false;
  2160. bt_plus.affiche(c2, 1); // fugitif
  2161.  
  2162. test_clic_boutons(&bt_moins );
  2163. bt_moins.affiche(c2, 1);
  2164. delay(100);
  2165. if (bt_moins.cliked)
  2166. {
  2167. efface_box_entete2();
  2168. if (frequence > saut_freq) // évite de se retrouver avec une F négative !
  2169. {
  2170. presetPad1.deselect_boutons();
  2171. bouton_cliked = true;
  2172. frequence -= saut_freq;
  2173. }
  2174. }
  2175.  
  2176. if(bt_moins.cliked && frequence > saut_freq) { Tune_Frequence(frequence); }
  2177. bt_moins.cliked = false;
  2178. bt_moins.selected = false;
  2179. bt_moins.affiche(c2, 1); // fugitif
  2180.  
  2181. if(bouton_cliked == true)
  2182. {
  2183. bouton_cliked = false;
  2184. affiche_frequence(frequence);
  2185. }
  2186. }
  2187.  
  2188. //-------------------------------------------------------------------------
  2189.  
  2190. if(mode_s == _MEM) // on va parcourir les fréquences de la liste
  2191. {
  2192. test_clic_boutons(&bt_plus );
  2193. bt_plus.affiche(c2, 1);
  2194. if (bt_plus.cliked)
  2195. {
  2196. bouton_cliked = true;
  2197.  
  2198. Serial.println("bt_plus.cliked");
  2199.  
  2200. if(groupe_actif == gSW) { frequence = inc_Frq_in_groupe(&groupe_SW, 1); }
  2201. if(groupe_actif == gFM) { frequence = inc_Frq_in_groupe(&groupe_FM, 1); }
  2202. if(groupe_actif == gAIR) { frequence = inc_Frq_in_groupe(&groupe_AIR, 1); }
  2203. if(groupe_actif == gSCN) { frequence = inc_Frq_in_groupe(&groupe_SCAN, 1); }
  2204.  
  2205. Tune_Frequence(frequence);
  2206. write_fichier_params();
  2207. vu_metre_actif = true;
  2208. dessine_VuMetre();
  2209. affiche_frequence(frequence);
  2210. delay(100);
  2211. }
  2212.  
  2213. bt_plus.cliked = false;
  2214. bt_plus.selected = false;
  2215. bt_plus.affiche(c2, 1); // fugitif
  2216.  
  2217. test_clic_boutons(&bt_moins );
  2218. bt_moins.affiche(c2, 1);
  2219. delay(100);
  2220. if (bt_moins.cliked)
  2221. {
  2222. bouton_cliked = true;
  2223.  
  2224. Serial.println("bt_moins.cliked");
  2225.  
  2226. if(groupe_actif == gSW) { frequence = inc_Frq_in_groupe(&groupe_SW, -1); }
  2227. if(groupe_actif == gFM) { frequence = inc_Frq_in_groupe(&groupe_FM, -1); }
  2228. if(groupe_actif == gAIR) { frequence = inc_Frq_in_groupe(&groupe_AIR, -1); }
  2229. if(groupe_actif == gSCN) { frequence = inc_Frq_in_groupe(&groupe_SCAN, -1); }
  2230.  
  2231. Tune_Frequence(frequence);
  2232. delay(100);
  2233. write_fichier_params();
  2234. vu_metre_actif = true;
  2235. dessine_VuMetre();
  2236. affiche_frequence(frequence);
  2237. }
  2238.  
  2239. bt_moins.cliked = false;
  2240. bt_moins.selected = false;
  2241. bt_moins.affiche(c2, 1); // fugitif
  2242.  
  2243. if(bouton_cliked == true)
  2244. {
  2245. bouton_cliked = false;
  2246. affiche_frequence(frequence);
  2247. }
  2248. }
  2249. }
  2250.  
  2251.  
  2252. void test_clic_bt_RST_affi() // bouton "ok" de la box saisie couleur de fond ecran
  2253. {
  2254. if(mode_affi != COUL) {return;}
  2255.  
  2256. uint16_t c1 = GRIS_6;
  2257. uint16_t c2 = JAUNE;
  2258.  
  2259. test_clic_boutons(&bt_RST_affi );
  2260.  
  2261. if (bt_RST_affi.cliked)
  2262. {
  2263. bt_RST_affi.cliked = false;
  2264. bt_RST_affi.selected = true;
  2265. bt_RST_affi.affiche(VERT, 1);
  2266.  
  2267. init_affichages();
  2268. }
  2269. }
  2270.  
  2271.  
  2272. void test_clic_bt_coul() // bouton au coin en bas à droite
  2273. {
  2274. uint16_t c1 = GRIS_5;
  2275. uint16_t c2 = BLANC;
  2276.  
  2277. uint8_t n;
  2278.  
  2279. test_clic_boutons(&bt_coul );
  2280.  
  2281. if (bt_coul.cliked)
  2282. {
  2283. bt_coul.cliked = false;
  2284. bt_coul.selected = true;
  2285. bt_coul.affiche(VERT, 1);
  2286.  
  2287. vu_metre_actif = false;
  2288.  
  2289. //delay(1000);
  2290. TFT.fillRect(x0_gridPad, y0_gridPad, dx_gridPad, dy_gridPad, NOIR);
  2291.  
  2292. gridPad1.init(x0_gridPad, y0_gridPad);
  2293. gridPad1.set_couleurs();
  2294. gridPad1.affiche();
  2295.  
  2296. boolean ok = false;
  2297.  
  2298. while(! ok)
  2299. {
  2300. if (ts.tirqTouched() && ts.touched())
  2301. {
  2302. get_XY_touch();
  2303. delay(100);
  2304. test_clic_bt_capture(); // capture écran
  2305. n = gridPad1.test_clic();
  2306. if (n != 253)
  2307. {
  2308. Serial.println(n);
  2309. if ((n != 32) && (n != 255))
  2310. {
  2311. couleur_fond_ecran = gridPad1.bt_grid[n].couleur;
  2312. write_fichier_params();
  2313. }
  2314. ok = true;
  2315. mode_affi = NORMAL;
  2316. vu_metre_actif = true;
  2317. init_affichages();
  2318. }
  2319. }
  2320. }
  2321. }
  2322. }
  2323.  
  2324.  
  2325.  
  2326. void test_clic_bouton_mute()
  2327. {
  2328. test_clic_boutons(&bt_mute );
  2329.  
  2330. if (bt_mute.cliked)
  2331. {
  2332. bt_mute.affiche(ROUGE, 1);
  2333. delay(10);
  2334.  
  2335. bt_mute.cliked = false;
  2336. if(mute == false) {mute = true;} else {mute = false;}
  2337. Set_Mute(mute); // fonction située dans le fichier 'driverTEF6686_628.h'
  2338. bt_mute.selected = mute;
  2339. bt_mute.affiche(ROUGE, 1);
  2340. if (mute == false) {Tune_Frequence(frequence);}
  2341. delay(10);
  2342. }
  2343. }
  2344.  
  2345.  
  2346. void test_clic_bt_quiet()
  2347. {
  2348. test_clic_boutons(&bt_quiet );
  2349. if (bt_quiet.cliked)
  2350. {
  2351. bt_quiet.cliked = false;
  2352. bt_quiet.selected = true;
  2353. bt_quiet.affiche(VERT, 1);
  2354.  
  2355. if(quiet==false)
  2356. {
  2357. quiet = true; // anti-parasites
  2358. vu_metre_actif = false;
  2359. affi_image_from_SD("/bmp565/montagne170x140b.bmp", x0_vu_metre, y0_vu_metre);
  2360. }
  2361. else
  2362. {
  2363. quiet = false;
  2364. vu_metre_actif = true;
  2365. dessine_VuMetre();
  2366. }
  2367.  
  2368. bt_quiet.cliked = false;
  2369. bt_quiet.selected = quiet;
  2370. bt_quiet.affiche(VERT, 1);
  2371. delay(300);
  2372. }
  2373. }
  2374.  
  2375.  
  2376. void test_clic_bouton_info()
  2377. {
  2378. test_clic_boutons(&bt_info);
  2379. if (bt_info.cliked)
  2380. {
  2381. bt_info.cliked = false;
  2382. bt_info.selected = true;
  2383. bt_info.affiche(VERT, 1);
  2384. delay(10);
  2385.  
  2386. // affiche une page d'information:
  2387.  
  2388. TFT.fillScreen(NOIR);
  2389. TFT.setTextColor(JAUNE, NOIR);
  2390. TFT.setFreeFont(FF1);
  2391. uint16_t y=0;
  2392. TFT.drawString("Radio TEF6686", 0, y); y+=20;
  2393. String s1="version " + version;
  2394. TFT.drawString(s1, 0, y); y+=20;
  2395.  
  2396. TFT.setTextColor(CYAN, NOIR);
  2397. TFT.drawString("Silicium628", 0, y); y+=40;
  2398.  
  2399. TFT.setTextColor(BLANC, NOIR);
  2400. TFT.setFreeFont(FF0);
  2401. TFT.drawString("SW (AM): 1500kHz -- 28MHz", 0, y); y+=20;
  2402. TFT.drawString("bande FM (WFM): 88MHz -- 108MHz", 0, y); y+=20;
  2403. TFT.drawString("bande Aviation Civile: 118MHz -- 137MHz (AM)", 0, y); y+=20;
  2404. //delay(10);
  2405.  
  2406. attente_clic();
  2407.  
  2408. }
  2409. }
  2410.  
  2411.  
  2412. void test_clic_bt_capture() // capture écran
  2413. {
  2414. test_clic_boutons(&bt_capture);
  2415. if (bt_capture.cliked)
  2416. {
  2417. bt_capture.cliked = false;
  2418. bt_capture.selected = true;
  2419. bt_capture.affiche(VERT, 1);
  2420. delay(10);
  2421.  
  2422. write_TFT_on_SDcard();
  2423. }
  2424. }
  2425.  
  2426.  
  2427. void affi_message(String L1, String L2, String L3, String L4, String L5)
  2428. {
  2429. TFT.fillScreen(NOIR);
  2430. TFT.setTextColor(BLANC, NOIR);
  2431. TFT.setFreeFont(FF1);
  2432. uint16_t y = 50;
  2433. uint16_t dy = 20;
  2434. TFT.drawString(L1, 20, y); y+=dy;
  2435. TFT.drawString(L2, 20, y); y+=dy;
  2436. TFT.drawString(L3, 20, y); y+=dy;
  2437. TFT.drawString(L4, 20, y); y+=dy;
  2438. TFT.drawString(L5, 20, y);
  2439.  
  2440. delay(10);
  2441. attente_clic();
  2442.  
  2443. }
  2444.  
  2445.  
  2446.  
  2447.  
  2448. void test_clic_bouton_Sleep()
  2449. {
  2450. test_clic_boutons(&bt_sleep );
  2451.  
  2452. if (bt_sleep.cliked)
  2453. {
  2454. bt_sleep.cliked = false;
  2455. bt_sleep.selected = true;
  2456. bt_sleep.affiche(ROUGE, 1);
  2457. delay(10);
  2458.  
  2459. //todo: save en SD
  2460. TFT.fillScreen(NOIR);
  2461. TFT.setTextColor(BLANC, NOIR);
  2462. TFT.setFreeFont(FF1);
  2463. TFT.drawString("Cliquez pour MODE SLEEP", 20, 50);
  2464. TFT.drawString("de l'ESP32", 20, 70);
  2465. TFT.drawString("Eteindre pour quitter", 20, 90);
  2466. TFT.drawString("ce mode SLEEP", 20, 110);
  2467.  
  2468. delay(10);
  2469.  
  2470. attente_clic();
  2471.  
  2472. esp_deep_sleep_start();
  2473. }
  2474. }
  2475.  
  2476.  
  2477. void test_clic_bt_LED()
  2478. {
  2479. test_clic_boutons(&bt_LED );
  2480.  
  2481. if (bt_LED.cliked)
  2482. {
  2483. bt_LED.cliked = false;
  2484. bt_LED.selected = true;
  2485. bt_LED.affiche(ROUGE, 1);
  2486. delay(10);
  2487.  
  2488. TFT.fillScreen(NOIR);
  2489. TFT.setTextColor(BLANC, NOIR);
  2490. TFT.setFreeFont(FF1);
  2491. TFT.drawString("ECRAN NOIR", 20, 50);
  2492. TFT.drawString("Clic pour rallumer", 20, 90);
  2493.  
  2494. for(int n=10; n>0; n--)
  2495. {
  2496. TFT.drawString(String(n) + " ", 20, 110);
  2497. delay(500);
  2498. }
  2499.  
  2500. digitalWrite(GPIO_BL, LOW);
  2501. attente_clic();
  2502. digitalWrite(GPIO_BL, HIGH);
  2503. }
  2504. }
  2505.  
  2506.  
  2507. void test_clic_bt_CAL()
  2508. {
  2509. test_clic_boutons(&bt_cal );
  2510.  
  2511. if (bt_cal.cliked)
  2512. {
  2513. bt_cal.cliked = false;
  2514. bt_cal.selected = true;
  2515. bt_cal.affiche(BLEU, 1);
  2516. delay(10);
  2517.  
  2518. TFT.fillScreen(NOIR);
  2519. TS_calibrate();
  2520. }
  2521. }
  2522.  
  2523.  
  2524.  
  2525. uint16_t read_16(File fp)
  2526. {
  2527. uint8_t low;
  2528. uint16_t high;
  2529. low = fp.read();
  2530. high = fp.read();
  2531. return (high<<8)|low;
  2532. }
  2533.  
  2534.  
  2535. uint32_t read_32(File fp)
  2536. {
  2537. uint16_t low;
  2538. uint32_t high;
  2539. low = read_16(fp);
  2540. high = read_16(fp);
  2541. return (high<<8)|low;
  2542. }
  2543.  
  2544.  
  2545. void affi_image_from_SD(String filename, uint16_t x0, uint16_t y0)
  2546. {
  2547. Serial.println("----------------------------");
  2548. Serial.println("affi_image_from_SD()");
  2549.  
  2550. uint8_t bmp_data[2]={0,0};
  2551. uint8_t a, b;
  2552. uint16_t x=0;
  2553. uint16_t y=0;
  2554. int16_t xmax;
  2555.  
  2556. uint32_t seekOffset;
  2557. uint16_t w, h, row, col;
  2558.  
  2559.  
  2560. File fp = SD.open(filename, "r");
  2561. if (!fp) { Serial.println("ERREUR open file on SD"); return; }
  2562.  
  2563. uint16_t etiq1 = read_16(fp);
  2564.  
  2565. // test bmp_header
  2566. if (etiq1 == 0x4D42)
  2567. {
  2568. read_32(fp);
  2569. read_32(fp);
  2570. seekOffset = read_32(fp);
  2571. Serial.print("seekOffset ="); Serial.println(seekOffset); // 138
  2572.  
  2573. Serial.print("seekOffset= "); Serial.println(seekOffset);
  2574. read_32(fp);
  2575. w = read_32(fp);
  2576. h = read_32(fp);
  2577. Serial.print("w= "); Serial.println(w); // 75
  2578. Serial.print("h= "); Serial.println(h); // 50
  2579. Serial.println(read_16(fp)); // 1
  2580. Serial.println(read_16(fp)); // 16
  2581. Serial.println(read_16(fp)); // 3
  2582. fp.seek(seekOffset);
  2583. }
  2584.  
  2585. y += h;
  2586. xmax = w;
  2587. if(xmax%2 == 1) {xmax +=1;}
  2588.  
  2589. uint16_t padding = (4 - ((w * 2) & 2)) & 2;
  2590. uint8_t lineBuffer[(w*2) + padding];
  2591.  
  2592. for (row = 0; row < h; row++)
  2593. {
  2594. fp.read(lineBuffer, sizeof(lineBuffer));
  2595. uint8_t* bptr = lineBuffer;
  2596. uint16_t* tptr = (uint16_t*)lineBuffer;
  2597.  
  2598. for (uint16_t col = 0; col < w; col++)
  2599. {
  2600. a = *bptr++;
  2601. b = *bptr++;
  2602. *tptr++ = (a <<8 | b);
  2603. }
  2604. TFT.pushImage(x0 + x, y0 + y, w, 1, (uint16_t*)lineBuffer);
  2605. y--;
  2606. }
  2607. fp.close();
  2608. }
  2609.  
  2610. /*
  2611. void ajout_1_freq()
  2612. {
  2613. // AJOUT d'une fréquence en fin d'une liste de fréquences. Travaille directement sur la mémoire SD
  2614. File file = SD.open("/FRQ_FM.txt", FILE_APPEND);
  2615. file.print("<88800>"); // ok ; attention à ne pas oublier les < >
  2616. file.close(); // enregistre CE fichier en mémoire SD, sans toucher aux autres
  2617. delay(100);
  2618. }
  2619. */
  2620.  
  2621.  
  2622. void affi_nuances_de_gris()
  2623. {
  2624. TFT.fillScreen(NOIR);
  2625. uint16_t x, dx, y;
  2626. x=30;
  2627. dx=21;
  2628. y=100;
  2629. TFT.fillRect(x, y, dx, dx, BLANC); x+=dx;
  2630. TFT.fillRect(x, y, dx, dx, GRIS_1); x+=dx;
  2631. TFT.fillRect(x, y, dx, dx, GRIS_2); x+=dx;
  2632. TFT.fillRect(x, y, dx, dx, GRIS_3); x+=dx;
  2633. TFT.fillRect(x, y, dx, dx, GRIS_4); x+=dx;
  2634. TFT.fillRect(x, y, dx, dx, GRIS_5); x+=dx;
  2635. TFT.fillRect(x, y, dx, dx, GRIS_6); x+=dx;
  2636.  
  2637. attente_clic();
  2638.  
  2639. }
  2640.  
  2641.  
  2642. void TS_verif()
  2643. {
  2644. TFT.fillScreen(BLANC);
  2645. TFT.setTextColor(NOIR, BLANC);
  2646. TFT.setFreeFont(FF1);
  2647. TFT.drawString("VERIF CALIBRATION", 10, 50);
  2648.  
  2649. init_1_bouton(1, 280, 20, 20, 20, "X", &bt_close);
  2650. boolean stop = false;
  2651. while(! stop)
  2652. {
  2653. get_XY_touch();
  2654. test_clic_boutons(&bt_close );
  2655. if (bt_close.cliked)
  2656. {
  2657. bt_close.cliked = false;
  2658. stop = true;
  2659. }
  2660. delay(10);
  2661. }
  2662. TFT.fillScreen(NOIR);
  2663. init_affichages();
  2664. }
  2665.  
  2666.  
  2667. void TS_calibrate() // calibrage de l'écran tactile
  2668. {
  2669. uint8_t L = 20;
  2670. boolean ok;
  2671. String s1;
  2672.  
  2673. TFT.setTextColor(BLANC, NOIR);
  2674. TFT.setFreeFont(FF1);
  2675.  
  2676. // traitement point A
  2677. TFT.fillScreen(NOIR);
  2678. TFT.drawString("Cliquez sur le point A", 20, 50);
  2679. delay(300);
  2680. TFT.drawFastVLine(10, 0, L, JAUNE);
  2681. TFT.drawFastHLine(0, 10, L, JAUNE);
  2682. ok = false;
  2683. while (! ok)
  2684. {
  2685. if (ts.tirqTouched() && ts.touched())
  2686. {
  2687. memo_y_touch = y_touch;
  2688. TS_Point p = ts.getPoint();
  2689. s1 = "Ax=" + String(p.x) + " "; TFT.drawString(s1, 50, 100);
  2690. s1 = "Ay=" + String(p.y) + " "; TFT.drawString(s1, 50, 120);
  2691. delay(100);
  2692.  
  2693. if( (p.x<600) && (p.y < 600)) // évite de valider une position irréaliste
  2694. {
  2695. A.x = p.x; // point A : variable globale
  2696. A.y = p.y;
  2697. ok = true;
  2698. }
  2699. }
  2700. }
  2701.  
  2702. // traitement point B
  2703. TFT.fillScreen(NOIR);
  2704. delay(300);
  2705. TFT.drawString("Cliquez sur le point B", 20, 70);
  2706. TFT.drawFastVLine(310, 230-L/2, L, JAUNE);
  2707. TFT.drawFastHLine(310-L/2, 230, L, JAUNE);
  2708. ok = false;
  2709. while (! ok)
  2710. {
  2711. if (ts.tirqTouched() && ts.touched())
  2712. {
  2713. memo_y_touch = y_touch;
  2714. TS_Point p = ts.getPoint();
  2715. s1 = "Bx=" + String(p.x) + " "; TFT.drawString(s1, 50, 150);
  2716. s1 = "By=" + String(p.y) + " "; TFT.drawString(s1, 50, 170);
  2717. delay(100);
  2718.  
  2719. if( (p.x>3600) && (p.y > 3400)) // évite de valider une position irréaliste
  2720. {
  2721. B.x = p.x;
  2722. B.y = p.y;
  2723. ok = true;
  2724. }
  2725. }
  2726. }
  2727. TFT.fillScreen(NOIR);
  2728. TFT.drawString("Ok", 20, 60);
  2729. TFT.setFreeFont(FF0);
  2730. TFT.drawString("Write fichier params sur la SD", 10, 90);
  2731. write_fichier_params();
  2732. delay(1000);
  2733.  
  2734. TFT.fillScreen(NOIR);
  2735. init_affichages();
  2736.  
  2737. //TS_verif();
  2738. //printTouchToDisplay(); // POUR TESTER LA CALIBRATION DE L'ECRAN TACTILE
  2739. }
  2740.  
  2741.  
  2742. void affi_lst_codes_PI_RDS() // lecture directement sur la SDcard, pas de mise en mémoire RAM
  2743. {
  2744. Serial.println("liste_codes_RDS()");
  2745. int i = 1;
  2746. char buffer1[64];
  2747.  
  2748. //uint32_t valeur_lue;
  2749. uint16_t line_num;
  2750. uint16_t nombre =0;
  2751. uint16_t y=0;
  2752. String s1;
  2753. boolean stop = false;
  2754.  
  2755. TFT.fillScreen(NOIR);
  2756. TFT.setTextColor(BLANC, NOIR);
  2757. TFT.setFreeFont(FF0);
  2758. TFT.drawString("Liste codes PI RDS (en memoire SD)", 0, y);
  2759. y+=30;
  2760.  
  2761. init_1_bouton(1, 280, 20, 50, 15, "stop", &bt_annuler);
  2762. bt_annuler.affiche(BLANC, 1);
  2763.  
  2764. File file1 = SD.open("/RDS_codes_PI.lst", "r");
  2765. while (file1.available() && stop == false )
  2766. {
  2767. int nb_bytes = file1.readBytesUntil('\n', buffer1, sizeof(buffer1));
  2768. buffer1[nb_bytes] = 0; // zéro terminal afin d'obtenir un string
  2769. //if (line_num == i)
  2770. {
  2771. //if(s1 != "") // n'affiche pas les emplacements vides
  2772. {
  2773. nombre++;
  2774. s1 = String(nombre);
  2775. TFT.setTextColor(BLEU, NOIR);
  2776. TFT.drawString(s1, 5, y);
  2777.  
  2778. s1 = buffer1;
  2779. //s1 += " ";
  2780. TFT.setTextColor(BLANC, NOIR);
  2781. TFT.drawString(s1, 30, y);
  2782. y+=10;
  2783.  
  2784. if(y>230)
  2785. {
  2786. delay(500); //300
  2787. if (ts.tirqTouched() && ts.touched())
  2788. {
  2789. stop = true;
  2790. TFT.fillScreen(NOIR);
  2791. TFT.drawString("STOP", 100, 100);
  2792. return;
  2793. }
  2794. else
  2795. {
  2796. delay(300); //200
  2797. TFT.fillScreen(NOIR);
  2798. y=0;
  2799. TFT.drawString("Liste codes PI RDS (en memoire SD)", 0, y);
  2800. bt_annuler.affiche(BLANC, 1);
  2801. y+=30; //30
  2802. }
  2803. }
  2804. }
  2805. }
  2806. i++;
  2807.  
  2808. }
  2809. file1.close();
  2810. attente_clic2();
  2811. }
  2812.  
  2813.  
  2814. void affi_deroulant(String titre, String filename)
  2815. {
  2816. //decale le texte fichier texte vers le haut et le complète en bas comme dans un générique de film
  2817.  
  2818. delay(300);
  2819. uint16_t memo_line_H[1920]; // 1280
  2820. char buffer1[64];
  2821. String s1, s2, s3, s4;
  2822.  
  2823. TFT.setFreeFont(FF0);
  2824. TFT.fillScreen(NOIR);
  2825. TFT.drawRect(1, 0, 319, 165, BLANC);
  2826.  
  2827. TFT.setTextColor(JAUNE, NOIR);
  2828. TFT.drawString(titre, 10, 5);
  2829. TFT.drawFastHLine(1, 14, 318, GRIS_5);
  2830. TFT.setTextColor(BLANC, NOIR);
  2831.  
  2832.  
  2833. init_1_bouton(1, 280, 220, 50, 15, "stop", &bt_annuler);
  2834. bt_annuler.affiche(BLANC, 1);
  2835.  
  2836. File file1 = SD.open(filename, "r");
  2837. int n=0;
  2838. boolean stop = false;
  2839. while (file1.available() && stop == false )
  2840. {
  2841. for(int y=22; y<160; y+=6) // 4
  2842. {
  2843. TFT.readRect(2, y, 317, 6, memo_line_H); // 4 mémorise la ligne
  2844. TFT.pushRect(2, y-4, 317, 6, memo_line_H); // la recopie un ligne au dessus
  2845. }
  2846. if(n%3 == 0) // 2
  2847. {
  2848. int nb_bytes = file1.readBytesUntil('\n', buffer1, sizeof(buffer1));
  2849. buffer1[nb_bytes] = 0; // zéro terminal afin d'obtenir un string
  2850.  
  2851. s1 = String(n/3); // 2
  2852. s2 = buffer1;
  2853. s3 = s2.substring(0, 4);
  2854. s4 = s2.substring(5);
  2855. //TFT.fillRect(10, 148, 339, 8, NOIR);
  2856. TFT.setTextColor(BLEU, NOIR);
  2857. TFT.drawString(s1, 10, 148);
  2858. TFT.setTextColor(JAUNE, NOIR);
  2859. TFT.drawString(s3, 40, 148);
  2860. TFT.setTextColor(GRIS_3, NOIR);
  2861. TFT.drawString(s4, 70, 148);
  2862.  
  2863. }
  2864. n++;
  2865. if ((ts.tirqTouched() && ts.touched()))
  2866. {
  2867. get_XY_touch();
  2868. test_clic_boutons(&bt_annuler);
  2869. if (bt_annuler.cliked)
  2870. {
  2871. bt_annuler.cliked = false;
  2872. TFT.fillScreen(NOIR);
  2873. x_touch = 0;
  2874. y_touch = 0;
  2875. delay(500);
  2876. stop = true;
  2877. }
  2878. }
  2879. }
  2880. file1.close();
  2881. }
  2882.  
  2883.  
  2884.  
  2885. void test_clic_bouton_TEST()
  2886. {
  2887. test_clic_boutons(&bt_TEST );
  2888. bt_TEST.affiche(ROUGE, 1);
  2889. if (bt_TEST.cliked)
  2890. {
  2891. delay(10);
  2892. Serial.println("-------------------------------");
  2893. Serial.println("bt_TEST.cliked");
  2894. bt_TEST.cliked = false;
  2895. bt_TEST.selected = true;
  2896. bt_TEST.affiche(ROUGE, 1);
  2897.  
  2898. //TFT.fillscreen(GRIS_3); // effface
  2899. //affi_image_from_SD("/7.bmp");
  2900. //ajout_1_freq();
  2901. /*
  2902. uint16_t dx= 40;
  2903. uint16_t dy =30;
  2904. uint16_t memo_line_H[dx*dy];
  2905. TFT.readRect(20, 20 , dx, dy, memo_line_H);
  2906. TFT.pushRect(100, 100, dx, dy, memo_line_H);
  2907. */
  2908. /*
  2909. String s1;
  2910. for (int n=0; n<10; n++)
  2911. {
  2912. s1 = read_line_params(n);
  2913. Serial.println(s1);
  2914. }
  2915. */
  2916. //TS_calibrate();
  2917.  
  2918. //affi_nuances_de_gris();
  2919.  
  2920. //TFT.fillScreen(NOIR); // effface
  2921. //draw_AEC(0, 100, 320, 1);
  2922.  
  2923. //affi_lst_codes_PI_RDS();
  2924. //TFT.fillScreen(GRIS_3); // effface
  2925.  
  2926. //affi_deroulant("Liste codes PI RDS", "/RDS_codes_PI.lst");
  2927.  
  2928. //TFT.drawString("Lecture faite", 10, 90);
  2929. //attente_clic2();
  2930.  
  2931. bt_TEST.cliked = false;
  2932. bt_TEST.selected = false;
  2933. bt_TEST.affiche(ROUGE, 1);
  2934.  
  2935. init_affichages();
  2936. Serial.println("-------------------------------");
  2937. }
  2938. }
  2939.  
  2940.  
  2941. void test_clic_Bt_reset()
  2942. {
  2943. test_clic_boutons(&bt_reset );
  2944. bt_reset.affiche(NOIR, 1);
  2945. if (bt_reset.cliked)
  2946. {
  2947. delay(10);
  2948. bt_reset.cliked = false;
  2949. bt_reset.selected = true;
  2950. bt_reset.affiche(VERT, 1);
  2951.  
  2952. delay(10);
  2953. bt_reset.selected = false;
  2954. bt_reset.affiche(VERT, 1);
  2955.  
  2956. setup();
  2957. }
  2958. }
  2959.  
  2960.  
  2961. void test_clic_bt_LEV()
  2962. {
  2963. test_clic_boutons(&bt_LEV);
  2964. if (bt_LEV.cliked)
  2965. {
  2966. bt_LEV.cliked = false;
  2967. bt_LEV.selected = true; bt_LEV.affiche(VERT, 1);
  2968. bt_SNR.selected = false; bt_SNR.affiche(VERT, 1);
  2969. mode_seuil = LEV;
  2970. }
  2971. }
  2972.  
  2973.  
  2974. void test_clic_bt_SNR()
  2975. {
  2976. test_clic_boutons(&bt_SNR);
  2977. if (bt_SNR.cliked)
  2978. {
  2979. bt_SNR.cliked = false;
  2980. bt_SNR.selected = true; bt_SNR.affiche(VERT, 1);
  2981. bt_LEV.selected = false; bt_LEV.affiche(VERT, 1);
  2982. mode_seuil = SNR;
  2983. }
  2984. }
  2985.  
  2986.  
  2987.  
  2988. void test_clic_bt_stop_scan()
  2989. {
  2990. test_clic_boutons(&bt_stop_scan);
  2991. if (bt_stop_scan.cliked)
  2992. {
  2993. Serial.println("STOP scan");
  2994. bt_stop_scan.affiche(BLANC, 1);
  2995. mode_affi = NORMAL;
  2996. bt_stop_scan.cliked = false;
  2997. bt_stop_scan.affiche(BLANC, 1);
  2998. }
  2999. }
  3000.  
  3001.  
  3002. void test_clic_bt_annuler()
  3003. {
  3004. test_clic_boutons(&bt_annuler);
  3005. if (bt_annuler.cliked)
  3006. {
  3007. bt_annuler.cliked = false;
  3008. bt_annuler.affiche(BLANC, 1);
  3009.  
  3010. mode_affi = NORMAL; // ce qui repasse les boutons 'preset' en mode sélection et empêche l'écriture en SD
  3011. vu_metre_actif = true;
  3012. init_affichages();
  3013. }
  3014. }
  3015.  
  3016.  
  3017. /*
  3018. MODES DE SCAN
  3019. 1-scan_frq() : tt fréquences d'une bande (ex: FM). Mise en mémoire temporaire (en RAM) des stations actives.
  3020. 2-scan_mem_AIR() : cannaux occupés (pour la bande aviation) - pas de mise en mémoire mais stop si message reçu
  3021. puis reprise auto du scan à la fin du message.
  3022. */
  3023.  
  3024. //enum MODE_SEUIL {LEV, SNR}; // level ou signal/bruit
  3025. //MODE_SEUIL mode_seuil = LEV;
  3026.  
  3027.  
  3028.  
  3029.  
  3030. void scan_mem_AIR()
  3031. {
  3032. // le scan de la bande aviation civile nécessite un convertisseur de fréquence 110MHz en entrée antenne
  3033. // le scan_AIR ne teste pas toutes les fréquences de la gamme mais seulement celles prédéfinies
  3034. // dans le fichier 'FRQ_AIR.txt' (sur la SDcard)
  3035. // ces fréquences peuvent avoir été écrites par le programme (touche 'Write') ou manuellement
  3036. // avec un éditeur de texte en respectant le syntaxe, par exemple <123500>
  3037.  
  3038. Serial.println("scan_mem_AIR()");
  3039. bande_active = AIR;
  3040.  
  3041. efface_box_GROUPE();
  3042. TFT.fillScreen(couleur_fond_ecran);
  3043.  
  3044. uint16_t couleur_ciel = 10739;
  3045.  
  3046. TFT.fillRect(x0_box_SCAN, y0_box_SCAN, dx_box_SCAN, dy_box_SCAN, GRIS_6);
  3047. affi_image_from_SD("/bmp565/avion1.bmp", 1, 80);
  3048.  
  3049. affiche_box_scan(dy_box_SCAN);
  3050.  
  3051. TFT.setFreeFont(FF0);
  3052. TFT.setTextColor(JAUNE, NOIR);
  3053.  
  3054. TFT.fillRect(2, 2, 42, 80, couleur_ciel); // efface
  3055.  
  3056. affi_image_from_SD("/bmp565/avion3.bmp", 1, 15);
  3057. affi_image_from_SD("/bmp565/PFD42x28.bmp", 1, 40);
  3058.  
  3059. String si;
  3060. uint16_t y;
  3061. uint16_t xi, yi;
  3062. int16_t dy;
  3063.  
  3064. int16_t attente =0;
  3065. int16_t signal_i;
  3066. uint16_t base = y0_box_SCAN + dy_box_SCAN -5; // bas du graphique
  3067. uint16_t memo_line_H[320];
  3068.  
  3069. mode_seuil = SNR; //2 types de détection possibles: LEV(level) et SNR(signal-to-noise ratio = signal/bruit)
  3070. bt_SNR.selected = true; bt_SNR.affiche(VERT, 1);
  3071. bt_LEV.selected = false; bt_LEV.affiche(VERT, 1);
  3072.  
  3073. TFT.setFreeFont(FM9);
  3074. TFT.setTextColor(JAUNE, NOIR);
  3075.  
  3076. frequence = 124075;
  3077. Tune_Frequence(frequence);
  3078. affiche_frequence(frequence);
  3079.  
  3080. TFT.readRect(0, base - seuil , 319, 1, memo_line_H); // mémorise la ligne avant de tracer
  3081. TFT.drawFastHLine(0, base -seuil, 319, JAUNE); // seuil (trait horizontal sur toute la largeur)
  3082.  
  3083. while(mode_affi == SCAN_M)
  3084. {
  3085. y = y0_box_SCAN + 5;
  3086. uint8_t module;
  3087. if(bande_active == FM) {module = 32;} else {module = 33;}
  3088. Get_Quality( module, &status, &level, &usn, &wam, &offset, &bandwidth, &mod, &snr );
  3089.  
  3090. si = String(level);
  3091. TFT.drawString("level", x0_box_SCAN +25 , y);
  3092. TFT.drawString(si+" ", x0_box_SCAN +65 , y);
  3093. y+=15;
  3094.  
  3095. si = String(snr);
  3096. TFT.drawString("snr", x0_box_SCAN +25 , y);
  3097. TFT.drawString(si+" ", x0_box_SCAN +65 , y);
  3098. y+=20;
  3099.  
  3100. if (mode_seuil == LEV) { signal_i = level; } // attention! level peut être négatif (échelle log)
  3101. if (mode_seuil == SNR) { signal_i= 16 * snr; }
  3102.  
  3103. dy = signal_i/10;
  3104. if(dy<0) {dy=0;}
  3105. dy+=2;
  3106.  
  3107. // petites barres verticales
  3108. xi = (frequence - 120000)/50;
  3109. // xi(120MHz) = 0 px;
  3110. // xi(136MHz) = (136000 - 120000) /50 = 320 px
  3111.  
  3112. //TFT.drawFastVLine(xi, base-50, 50, couleur_ciel); // 95 efface
  3113. uint16_t c0 = BLEU;
  3114. if(signal_i > seuil*10){c0 = JAUNE;}
  3115. TFT.drawFastVLine(xi, base -dy, dy, c0);
  3116.  
  3117. if(signal_i > seuil*10)
  3118. {
  3119. TFT.fillRect(x0_box_SCAN +100, y0_box_SCAN + 20, 20, 20, VERT); // carré coloré
  3120. attente = 2;
  3121. }
  3122. else attente --;
  3123.  
  3124. if (attente <=0)
  3125. {
  3126. TFT.fillRect(x0_box_SCAN +100, y0_box_SCAN + 20, 20, 20, GRIS_5); // carré coloré
  3127. frequence = inc_Frq_in_groupe(&groupe_AIR, 1);
  3128. Tune_Frequence(frequence);
  3129. affiche_frequence(frequence);
  3130. TFT.setFreeFont(FF0);
  3131. TFT.setTextColor(BLANC, NOIR);
  3132. TFT.drawString("120MHz", x0_box_SCAN +5 , base-10);
  3133. TFT.drawString("136", x0_box_SCAN +dx_box_SCAN -22, base-10);
  3134.  
  3135. attente =0;
  3136. }
  3137.  
  3138. delay(50); // ne pas réduire, temps nécessaire pour accrocher la fréquence
  3139.  
  3140. if (ts.tirqTouched() && ts.touched())
  3141. {
  3142. get_XY_touch();
  3143. test_clic_bt_stop_scan();
  3144. test_clic_bt_capture(); // capture écran
  3145.  
  3146. test_clic_boutons(&bt_seuil_plus);
  3147. if (bt_seuil_plus.cliked)
  3148. {
  3149. bt_seuil_plus.cliked = false;
  3150. TFT.pushRect(0, base - memo_seuil, 319, 1, memo_line_H); // efface avec l'image enregistrée
  3151. memo_seuil = seuil;
  3152. seuil += 1;
  3153. if (seuil > 120) {seuil = 120;}
  3154. TFT.readRect(0, base - seuil , 319, 1, memo_line_H); // mémorise la ligne avant de tracer
  3155. TFT.drawFastHLine(0, base -seuil, 319, JAUNE); // seuil (trait horizontal sur toute la largeur)
  3156. TFT.setFreeFont(FF0); TFT.setTextColor(JAUNE, NOIR);
  3157. si = "seuil:" + String(seuil*10); TFT.drawString(si+" ", x0_box_SCAN +190 , y0_box_SCAN +15);
  3158. }
  3159.  
  3160. test_clic_boutons(&bt_seuil_moins);
  3161. if (bt_seuil_moins.cliked)
  3162. {
  3163. bt_seuil_moins.cliked = false;
  3164. TFT.pushRect(0, base - memo_seuil, 319, 1, memo_line_H); // efface avec l'image enregistrée
  3165. memo_seuil = seuil;
  3166. seuil -= 1;
  3167. if (seuil < 5) {seuil = 5;}
  3168. TFT.readRect(0, base - seuil , 319, 1, memo_line_H); // mémorise la ligne avant de tracer
  3169. TFT.drawFastHLine(0, base -seuil, 319, JAUNE); // seuil (trait horizontal sur toute la largeur)
  3170. TFT.setFreeFont(FF0); TFT.setTextColor(JAUNE, NOIR);
  3171. si = "seuil:" + String(seuil*10); TFT.drawString(si+" ", x0_box_SCAN +190 , y0_box_SCAN +15);
  3172. }
  3173.  
  3174. test_clic_bt_LEV();
  3175. test_clic_bt_SNR();
  3176.  
  3177. test_clic_boutons(&bt_stop_scan);
  3178. }
  3179. }
  3180.  
  3181. //delay(1000);
  3182.  
  3183. mode_s = _MEM;
  3184. mode_affi = NORMAL;
  3185. bande_active = FM;
  3186. bt_mode_MEM.selected = true; bt_mode_MEM.affiche(VERT, 2);
  3187. bt_mode_FRQ.selected = false; bt_mode_FRQ.affiche(VERT, 2);
  3188.  
  3189. //boutons_preset_set_frequences();
  3190. init_affichages();
  3191. frequence = 89400;
  3192. Tune_Frequence(frequence);
  3193. affiche_frequence(frequence);
  3194.  
  3195. bt_FM.selected = true; bt_FM.affiche(VERT, 1);
  3196. bt_AIR.selected = false; bt_AIR.affiche(VERT, 1);
  3197. }
  3198.  
  3199.  
  3200. void affi_passes(String band_name, int num_passe, int nb_passes)
  3201. {
  3202. TFT.setTextColor(NOIR, BLANC); TFT.setFreeFont(FMB9);
  3203. String s1 = "SW bande" + band_name;
  3204. s1 += "_";
  3205. TFT.drawString(s1, 2, 14);
  3206. s1 = String(num_passe);
  3207. s1 += "/";
  3208. s1 += String(nb_passes);
  3209. TFT.drawString(s1, 284, 14); // en haut à droite
  3210. TFT.drawString(s1, 10, 200); // en bas à gauche
  3211. }
  3212.  
  3213.  
  3214. void scan_frq(uint32_t freq_iA, uint32_t freq_iB, String band_name) // toutes les fréquences de la bande, incrémental, saut_freq = constant
  3215. {
  3216. Serial.println("scan_frq()");
  3217. Serial.print("freq_iA = "); Serial.println(freq_iA);
  3218. Serial.print("freq_iB = "); Serial.println(freq_iB);
  3219.  
  3220. if(bande_active == SCN) {bande_active = FM;}
  3221.  
  3222. String si;
  3223. String s1;
  3224. String sA, sB;
  3225. float xi=0;
  3226. uint32_t xi32;
  3227. uint16_t y;
  3228. int16_t dy;
  3229. uint16_t yi;
  3230. uint32_t freq;
  3231. uint32_t largeur_bande = freq_iB - freq_iA;
  3232. uint16_t nb_F;
  3233. int n_max;
  3234. int nb_passes = 1;
  3235. int num_passe = 1;
  3236.  
  3237. int16_t signal_i;
  3238. uint16_t base = y0_box_SCAN + dy_box_SCAN -5; // bas du graphique
  3239. uint16_t memo_line_H[320];
  3240.  
  3241. uint16_t decal_x;
  3242. uint16_t decal_y;
  3243.  
  3244.  
  3245. TFT.fillScreen(couleur_fond_ecran);
  3246. TFT.fillRect(x0_box_SCAN, y0_box_SCAN, dx_box_SCAN, dy_box_SCAN, NOIR);
  3247. memo_freq = freq_iA; // variables globales
  3248.  
  3249. mode_seuil = SNR; //2 types de détection possibles: LEV(level) et SNR(signal-to-noise ratio = signal/bruit)
  3250. bt_SNR.selected = true; bt_SNR.affiche(VERT, 1);
  3251. bt_LEV.selected = false; bt_LEV.affiche(VERT, 1);
  3252.  
  3253. groupe_SCAN.RAZ();
  3254. efface_box_GROUPE();
  3255.  
  3256. //TFT.setFreeFont(FM9);
  3257. TFT.setTextColor(JAUNE, NOIR);
  3258. TFT.setFreeFont(FF0);
  3259.  
  3260. freq = freq_iA;
  3261.  
  3262. uint8_t module;
  3263. if(bande_active == FM)
  3264. {
  3265. saut_freq = 100; // kHz
  3266. module = 32;
  3267. n_max = 190;
  3268. nb_passes = 1;
  3269. }
  3270. else
  3271. {
  3272. saut_freq = 5; // kHz
  3273. module = 33;
  3274. n_max = largeur_bande / saut_freq;
  3275. nb_passes = 1 + n_max / 200;
  3276. if(nb_passes < 1) {nb_passes=1;}
  3277. }
  3278.  
  3279. y = y0_box_SCAN + 5;
  3280. decal_x=0;
  3281. decal_y=0;
  3282. nb_F=0;
  3283.  
  3284. // sA = String(freq);
  3285. // sB = String(freq + n_max * saut_freq);
  3286. // TFT.drawString(sA, x0_box_SCAN +5 , base-5);
  3287. // TFT.drawString(sB, x0_box_SCAN +dx_box_SCAN -40, base-5);
  3288.  
  3289. sA = String(freq_iA + (num_passe-1) * 200 * saut_freq);
  3290. sB = String(freq_iA + num_passe * 200 * saut_freq);
  3291. TFT.setTextColor(JAUNE, NOIR);
  3292. TFT.setFreeFont(FF0);
  3293. TFT.drawString(sA, x0_box_SCAN +5 , base-5);
  3294. TFT.drawString(sB, x0_box_SCAN +dx_box_SCAN -40, base-5);
  3295.  
  3296. TFT.readRect(0, base - seuil , 319, 1, memo_line_H); // mémorise la ligne avant de tracer
  3297. TFT.drawFastHLine(0, base -seuil, 319, VIOLET); // seuil (trait horizontal sur toute la largeur)
  3298.  
  3299. TFT.setTextColor(VIOLET, NOIR);
  3300. TFT.setFreeFont(FF0);
  3301. si = "seuil:" + String(seuil*10); TFT.drawString(si+" ", x0_box_SCAN +190 , y0_box_SCAN +15);
  3302.  
  3303. boolean scan_complet;
  3304. boolean rescan = false;
  3305. do
  3306. {
  3307. groupe_SCAN.RAZ();
  3308. nb_F = 0;
  3309. affiche_box_scan(dy_box_SCAN);
  3310. uint32_t freq_min = freq;
  3311.  
  3312. if(bande_active == SW)
  3313. {
  3314. affi_passes(band_name, num_passe, nb_passes);
  3315. s1 = "[" + String(freq_iA) + "-" + String(freq_iB) + "]";
  3316. TFT.setTextColor(BLANC, couleur_fond_ecran); TFT.setFreeFont(FF1);
  3317. TFT.drawString(s1, 145, 14);
  3318. }
  3319.  
  3320. //......................................................................
  3321. int n = n_max;
  3322. while((n>0) && !(bande_interdite1 || bande_interdite2))
  3323. {
  3324. if (ts.tirqTouched() && ts.touched()) // écran tactile
  3325. {
  3326. get_XY_touch();
  3327. test_clic_boutons(&bt_stop_scan);
  3328. if (bt_stop_scan.cliked)
  3329. {
  3330. //bt_stop_scan.cliked = false;
  3331. n=0; // force la sortie de la boucle while()
  3332. }
  3333. }
  3334.  
  3335. freq += saut_freq;
  3336. affiche_frequence(freq);
  3337.  
  3338. if( (freq + saut_freq) <= 138000 )
  3339. {
  3340. Tune_Frequence(freq);
  3341. delay(15);
  3342. }
  3343.  
  3344. if(bande_active == FM) {module = 32;} else {module = 33;}
  3345. Get_Quality( module, &status, &level, &usn, &wam, &offset, &bandwidth, &mod, &snr );
  3346.  
  3347. delay(50);
  3348. //if(bande_active == SW) {xi += 1.6;}
  3349. //if(bande_active == FM) {xi += 2;}
  3350. xi += 1.6;
  3351.  
  3352. if (mode_seuil == LEV) { signal_i = level; } // attention! level peut être négatif (échelle log)
  3353. if (mode_seuil == SNR) { signal_i= 16 * snr; }
  3354.  
  3355. dy = signal_i/10;
  3356. if(dy<0) {dy=0;}
  3357. dy-=5;
  3358.  
  3359. //uint16_t c1;
  3360. xi32 = x0_box_SCAN + (uint32_t)xi;
  3361.  
  3362. // BARRES VERTICALES ----------------------------
  3363.  
  3364. if (xi32 < 318) // limite d'affichage à droite
  3365. {
  3366. // on va les tracer les barres verticales point par point afin de pouvoir les coloriser
  3367. int a = base;
  3368. int b = a - dy;
  3369.  
  3370. uint16_t x, y1, j, L;
  3371. uint16_t couleur_i;
  3372. L = dy; // longueur (verticale) de la barre
  3373. for (int16_t i=0; i<L; i++)
  3374. {
  3375. float f = 10.0 * i; // pour balayer toute l'échelle des 470 couleurs disponibles
  3376. j=uint16_t(f);
  3377. if(j>460){j=460;}
  3378. couleur_i = couleurs_aec[2*j] | couleurs_aec[2*j+1]<<8; //couleurs arc-en-ciel, voir fichier Couleurs_AEC.h
  3379. y1=225-i;
  3380. TFT.drawPixel(xi32, y1, couleur_i);
  3381. }
  3382. }
  3383. else // on arrive en bout d'affichage à droite, on passe à la plage suivante si necessaire...
  3384. {
  3385. TFT.fillRect(x0_box_SCAN, y0_box_SCAN, dx_box_SCAN, dy_box_SCAN, NOIR);
  3386. affiche_box_scan(dy_box_SCAN); // efface le tracé et re-dessine les boutons dans la boite
  3387. TFT.readRect(0, base - seuil , 319, 1, memo_line_H); // mémorise la ligne avant de tracer
  3388. TFT.drawFastHLine(0, base -seuil, 319, VIOLET); // seuil (trait horizontal sur toute la largeur)
  3389. si = "seuil:" + String(seuil*10); TFT.drawString(si+" ", x0_box_SCAN +190 , y0_box_SCAN +15);
  3390. xi = 0;
  3391. num_passe ++;
  3392. if(bande_active == SW)
  3393. {
  3394. affi_passes(band_name, num_passe, nb_passes);
  3395. sA = String(freq_iA + (num_passe-1) * 200 * saut_freq);
  3396. sB = String(freq_iA + num_passe * 200 * saut_freq);
  3397. TFT.setTextColor(JAUNE, NOIR);
  3398. TFT.setFreeFont(FF0);
  3399. TFT.drawString(sA, x0_box_SCAN +5 , base-5);
  3400. TFT.drawString(sB, x0_box_SCAN +dx_box_SCAN -40, base-5);
  3401. }
  3402. }
  3403.  
  3404.  
  3405. // --------------------------------------------------
  3406. if(signal_i > seuil*10) // DETECTION
  3407. {
  3408. if (decal_y > 5) // concerne l'affichage des textes (fréquences trouvées)
  3409. {
  3410. decal_y = 0;
  3411. decal_x ++;
  3412. }
  3413.  
  3414. if((nb_F % 25) == 0) // limite le nb de freq affichées simultanément à 25
  3415. {
  3416. affiche_box_scan(dy_box_SCAN/2);
  3417. decal_x = 0;
  3418. decal_y = 0;
  3419. }
  3420.  
  3421. s1 = String(freq);
  3422. TFT.setTextColor(BLANC, NOIR);
  3423. TFT.drawString(s1, x0_box_SCAN + 20 + 45*decal_x, y0_box_SCAN + 9*decal_y); // affiche FREQUENCE
  3424. nb_F++;
  3425.  
  3426. TFT.setFreeFont(FF0);
  3427. TFT.setTextColor(VERT, NOIR);
  3428. s1 = String(nb_F);
  3429. TFT.drawString(s1, x0_box_SCAN +3 , y0_box_SCAN + 45); // nb freq
  3430. TFT.setFreeFont(FF0);
  3431.  
  3432. groupe_SCAN.add_frq(freq); // AJOUTE la fréquence trouvée au groupe spécial 'groupe_SCAN'
  3433. decal_y ++;
  3434.  
  3435. if(groupe_SCAN.nb_freq >= 100) // groupe plein (en RAM)
  3436. {
  3437. s1 = String(freq);
  3438. TFT.setTextColor(ROUGE, NOIR);
  3439. TFT.drawString(s1+" groupe SC plein", x0_box_SCAN +80 , y0_box_SCAN + 60);
  3440. TFT.setTextColor(BLANC, NOIR);
  3441. n=0;
  3442. }
  3443. }
  3444. n--;
  3445. //if (n<10) {scan_complet = true;}
  3446. delay(10); // ne pas réduire, temps nécessaire pour accrocher la fréquence
  3447. //delay(300); // pour balayage lent
  3448.  
  3449. if (ts.tirqTouched() && ts.touched()) // écran tactile
  3450. {
  3451. get_XY_touch();
  3452. test_clic_bt_capture(); // capture écran
  3453.  
  3454. test_clic_boutons(&bt_seuil_plus);
  3455. if (bt_seuil_plus.cliked)
  3456. {
  3457. bt_seuil_plus.cliked = false;
  3458. TFT.pushRect(0, base - memo_seuil, 319, 1, memo_line_H); // efface avec l'image enregistrée
  3459. memo_seuil = seuil;
  3460. seuil += 1;
  3461. if (seuil > 120) {seuil = 120;}
  3462. TFT.readRect(0, base - seuil , 319, 1, memo_line_H); // mémorise la ligne avant de tracer
  3463. TFT.drawFastHLine(0, base -seuil, 319, VIOLET); // seuil (trait horizontal sur toute la largeur)
  3464. TFT.setFreeFont(FF0); TFT.setTextColor(VIOLET, NOIR);
  3465. si = "seuil:" + String(seuil*10); TFT.drawString(si+" ", x0_box_SCAN +190 , y0_box_SCAN +15);
  3466. }
  3467.  
  3468. test_clic_boutons(&bt_seuil_moins);
  3469. if (bt_seuil_moins.cliked)
  3470. {
  3471. bt_seuil_moins.cliked = false;
  3472. TFT.pushRect(0, base - memo_seuil, 319, 1, memo_line_H); // efface avec l'image enregistrée
  3473. memo_seuil = seuil;
  3474. seuil -= 1;
  3475. if (seuil < 5) {seuil = 5;}
  3476. TFT.readRect(0, base - seuil , 319, 1, memo_line_H); // mémorise la ligne avant de tracer
  3477. TFT.drawFastHLine(0, base -seuil, 319, VIOLET); // seuil (trait horizontal sur toute la largeur)
  3478. TFT.setFreeFont(FF0); TFT.setTextColor(VIOLET, NOIR);
  3479. si = "seuil:" + String(seuil*10); TFT.drawString(si+" ", x0_box_SCAN +190 , y0_box_SCAN +15);
  3480. }
  3481.  
  3482. // modes de détection :
  3483. test_clic_bt_LEV(); // mode Level
  3484. test_clic_bt_SNR(); // mode Signal / bruit
  3485.  
  3486. test_clic_boutons(&bt_re_scan);
  3487. if (bt_re_scan.cliked)
  3488. {
  3489. bt_re_scan.cliked = false;
  3490. TFT.fillRect(x0_box_SCAN, y0_box_SCAN, dx_box_SCAN, dy_box_SCAN, NOIR);
  3491. affiche_box_scan(dy_box_SCAN); // efface le tracé et re-dessine les boutons dans la boite
  3492. freq = memo_freq; // on repart de ma même frequence
  3493. n = n_max;
  3494. xi =0; // départ tracé à gauche
  3495. decal_x=0; // textes fréquences trouvées
  3496. decal_y=0;
  3497. nb_F=0;
  3498. TFT.readRect(0, base - seuil , 319, 1, memo_line_H); // mémorise la ligne avant de tracer
  3499. TFT.drawFastHLine(0, base -seuil, 319, VIOLET); // seuil (trait horizontal sur toute la largeur)
  3500. si = "seuil:" + String(seuil*10); TFT.drawString(si+" ", x0_box_SCAN +190 , y0_box_SCAN +15);
  3501. }
  3502. }
  3503. } // fin de la boucle while()
  3504.  
  3505. //.......................................................................
  3506.  
  3507.  
  3508. if(nb_passes == 1) // because la fonction d'écoute au stylet incorrecte si spectre partiel
  3509. {
  3510. TFT.setTextColor(CYAN, NOIR);
  3511. TFT.setFreeFont(FF0);
  3512. TFT.drawString("On peut ecouter les freq", 10, 145);
  3513. TFT.drawString("en deplacant le stylet sur le spectre", 10, 155);
  3514. }
  3515.  
  3516. boolean stop = false;
  3517. while (! stop) // attend une action en fin de scan (par ex: clic sur bouton 'stop_scan' [x]) ou [re_scan]
  3518. {
  3519. if (ts.tirqTouched() && ts.touched())
  3520. {
  3521. get_XY_touch();
  3522.  
  3523. if((x_touch != memo_x_touch) && (y_touch > 170)) // écoute de la fréquence pointée avec le stylet
  3524. {
  3525. TFT.drawFastVLine(memo_x_touch, base, 4, NOIR); // efface
  3526. TFT.drawFastVLine(x_touch, base, 4, BLANC);
  3527.  
  3528. TFT.drawFastVLine(memo_x_touch, base-50, 4, NOIR); // efface
  3529. TFT.drawFastVLine(x_touch, base-50, 4, BLANC);
  3530.  
  3531. memo_x_touch = x_touch ;
  3532.  
  3533. float dF = (x_touch - x0_box_SCAN) * saut_freq / 1.6;
  3534. uint32_t F1 = freq_min + uint32_t(dF);
  3535. freq = F1;
  3536. affiche_frequence(freq);
  3537. Tune_Frequence(freq);
  3538. String sF1 = String(F1);
  3539. TFT.drawString(sF1, 200, 100);
  3540. }
  3541.  
  3542. test_clic_boutons(&bt_re_scan);
  3543. if (bt_re_scan.cliked)
  3544. {
  3545. bt_re_scan.cliked = false;
  3546. freq = memo_freq; // on repart de ma même frequence
  3547. xi=0;
  3548. xi32 = x0_box_SCAN + (uint32_t)xi;
  3549. stop =true;
  3550. rescan = true; //pas d'appel RECURSIF de la fonction. Trop de pb !!
  3551. }
  3552.  
  3553. test_clic_boutons(&bt_scan_suivant);
  3554. if (bt_scan_suivant.cliked)
  3555. {
  3556. bt_re_scan.cliked = false;
  3557. TFT.fillRect(x0_box_SCAN, y0_box_SCAN, dx_box_SCAN, dy_box_SCAN, NOIR);
  3558. affiche_box_scan(dy_box_SCAN); // efface le tracé et re-dessine les boutons dans la boite
  3559.  
  3560. n = n_max;
  3561. xi =0; // départ tracé à gauche
  3562. decal_x=0; // textes fréquences trouvées
  3563. decal_y=0;
  3564. nb_F=0;
  3565. memo_freq = freq;
  3566. stop =true; // sortira de la boucle while()
  3567. rescan = true; // bouclera dans la boucle do()
  3568. }
  3569.  
  3570. test_clic_boutons(&bt_stop_scan);
  3571. if (bt_stop_scan.cliked)
  3572. {
  3573. n=0;
  3574. stop =true; // sortira de la boucle while()
  3575. rescan = false; // ne rebouclera PAS dans la boucle do()
  3576. }
  3577. }
  3578. }
  3579.  
  3580. } while (rescan == true); // Fin de la boucle do()
  3581.  
  3582. groupe_SCAN.bloc_to_serial(); // pour test avec moniteur série (CuteCom par exemple)
  3583. mode_affi = NORMAL;
  3584. mode_s = _MEM;
  3585. bt_mode_FRQ.selected = false; bt_mode_FRQ.affiche(VERT, 2);
  3586. bt_mode_MEM.selected = true; bt_mode_MEM.affiche(VERT, 2);
  3587.  
  3588. write_fichier_params();
  3589.  
  3590. if (bt_stop_scan.cliked == false)
  3591. {
  3592. // si on est sorti de la boucle normalement, (pas par clic sur bouton stop), on passe ici
  3593. uint16_t ya = 20;
  3594. uint8_t dya = 15;
  3595. TFT.fillScreen(NOIR);
  3596. TFT.setTextColor(BLANC, NOIR);
  3597. TFT.setFreeFont(FF0);
  3598. TFT.drawString("Les Freq. detectees sont memo en RAM", 5, ya); ya += dya;
  3599. TFT.drawString("accessibles par le bouton 'SC'", 5, ya); ya += dya;
  3600. TFT.drawString("On peut les enregistrer en SD", 5, ya); ya += dya;
  3601. TFT.drawString("une a une avec le bouton 'Write'", 5, ya); ya += dya;
  3602. TFT.drawString("sinon -> perdues si stop radio", 5, ya); ya += dya;
  3603. attente_clic();
  3604. delay(300);
  3605. }
  3606. }
  3607.  
  3608.  
  3609. void choix_type_scan()
  3610. {
  3611. TFT.fillScreen(NOIR);
  3612. TFT.setTextColor(BLANC, NOIR);
  3613. TFT.setFreeFont(FF1);
  3614. TFT.drawString("CHOIX TYPE SCAN", 10, 5);
  3615.  
  3616. init_1_bouton(2, 10, 70, 85, 20, "scan SW", &bt_scan_SW);
  3617. init_1_bouton(2, 120, 70, 85, 20, "scan FM", &bt_scan_FM);
  3618. init_1_bouton(2, 60, 100, 95, 20, "scan AIR", &bt_scan_air);
  3619.  
  3620. boolean ok1 = false;
  3621. while (! ok1)
  3622. {
  3623. if ((ts.tirqTouched() && ts.touched()))
  3624. {
  3625. get_XY_touch();
  3626. test_clic_boutons(&bt_scan_SW);
  3627. if (bt_scan_SW.cliked == true)
  3628. {
  3629. ok1 = true;
  3630. // -------------------------- BANDES SW choisies ----------------
  3631. bt_scan_SW.cliked = false;
  3632. TFT.fillScreen(NOIR);
  3633. TFT.setTextColor(JAUNE, NOIR);
  3634. TFT.setFreeFont(FF0);
  3635. TFT.drawString("CHOIX BANDE SW", 230, 2);
  3636. swPad1.init(5, 2); // initialise et affiche les 14 boutons des 14 bandes d'ondes courtes (SW)
  3637. swPad1.set_frequences_SW();// voir la fonction 'void SW_PAD::set_frequences_SW()' pour les fréquences SW
  3638.  
  3639. affi_image_from_SD("/bmp565/3r.bmp", 150, 60);
  3640.  
  3641. boolean ok2 = false;
  3642. while (! ok2)
  3643. {
  3644. if ((ts.tirqTouched() && ts.touched()))
  3645. {
  3646. // ---------------- choix de la bande AM SW (impose la fréquence de départ) ---------------
  3647. get_XY_touch();
  3648. uint8_t n = swPad1.test_clic();
  3649.  
  3650. uint32_t FA = swPad1.bt_SW[n].freq_A; // fréquence de départ du scan AM
  3651. uint32_t FB = swPad1.bt_SW[n].freq_B; // fréquence de fin du scan AM
  3652.  
  3653. if (FA != 0) // si on n'a pas cliqué en dehors des clous...
  3654. {
  3655. String band_name = " "; // espace à gauche
  3656. uint16_t L = swPad1.bt_SW[n].lambda;
  3657. band_name += String(L)+"m";
  3658. TFT.setTextColor(NOIR, BLANC);
  3659. TFT.setFreeFont(FMB12);
  3660. TFT.drawString(band_name + " ", 150, 10);
  3661.  
  3662. String s2 = String(FA) + ".." + String(FB)+ " kHz";
  3663. TFT.setTextColor(JAUNE, NOIR);
  3664. TFT.setFreeFont(FF1);
  3665. TFT.drawString(s2, 140, 35);
  3666.  
  3667. bande_active = SW;
  3668. ok2=true;
  3669. mode_affi = SCAN_F;
  3670. mode_s = _FRQ;
  3671. delay(2500);
  3672. scan_frq(FA, FB, band_name); // scanner (AM-SW ou FM )
  3673. }
  3674. }
  3675. }
  3676. }
  3677.  
  3678. if ((ts.tirqTouched() && ts.touched()))
  3679. {
  3680. get_XY_touch();
  3681. test_clic_boutons(&bt_scan_FM);
  3682. if (bt_scan_FM.cliked == true)
  3683. {
  3684. // ------------------------------ BANDE FM choisie -----------------
  3685. bt_scan_FM.cliked = false;
  3686. bande_active = FM;
  3687. ok1=true;
  3688. mode_affi = SCAN_F;
  3689. mode_s = _FRQ;
  3690. scan_frq(88000, 108000, "bande FM");
  3691. }
  3692. }
  3693.  
  3694. test_clic_boutons(&bt_scan_air);
  3695. if (bt_scan_air.cliked == true)
  3696. {
  3697. // ------------------------------ BANDE AIR ----------------
  3698. bt_scan_air.cliked = false;
  3699. mode_affi = SCAN_M;
  3700. bande_active == AIR;
  3701. ok1=true;
  3702. scan_mem_AIR();
  3703. mode_s = _MEM;
  3704. }
  3705. }
  3706. }
  3707. }
  3708.  
  3709.  
  3710.  
  3711. void test_clic_Bt_SCAN()
  3712. {
  3713. if ((ts.tirqTouched() && ts.touched()))
  3714. {
  3715. get_XY_touch();
  3716. test_clic_boutons(&Bt_SCAN);
  3717. if (Bt_SCAN.cliked == true)
  3718. {
  3719. Bt_SCAN.cliked = false;
  3720. choix_type_scan(); // choix bande à scanner (SW - FM) et type FRQ ou AIR (puis déclenche le scan)
  3721.  
  3722. init_affichages();
  3723.  
  3724. groupe_actif = gSCN;
  3725. bande_active = SCN;
  3726.  
  3727. //bt_SCN.selected = true; bt_SCN.affiche(CYAN, 1);
  3728. bt_SW.selected = false; bt_SW.affiche(VERT, 1);
  3729. bt_FM.selected = false; bt_FM.affiche(VERT, 1);
  3730. bt_AIR.selected = false;bt_AIR.affiche(VERT, 1);
  3731.  
  3732. //affiche_numero_frq(String(1), String(nb_F));
  3733. affiche_frequence(frequence);
  3734. }
  3735. }
  3736. }
  3737.  
  3738.  
  3739.  
  3740. void retour_normal()
  3741. {
  3742. TFT.fillScreen(NOIR);
  3743. init_affichages();
  3744. //bt_SW.selected = false;
  3745. //bt_FM.selected = true;
  3746. //bande_active = FM;
  3747. //modulation_active = WFM;
  3748. //frequence = presetPad1.bt_preset[0].frequence_FM;
  3749. //bt_SW.affiche(VERT, 1);
  3750. //bt_FM.affiche(VERT, 1);
  3751. }
  3752.  
  3753.  
  3754. void attente_clic()
  3755. {
  3756. delay(300);
  3757. init_1_bouton(1, 300, 5, 20, 20, "X", &bt_close);
  3758. while ( !(ts.tirqTouched() && ts.touched()) ) {;}
  3759. retour_normal();
  3760.  
  3761. }
  3762.  
  3763.  
  3764.  
  3765. void attente_clic2() // et anti-parasite !!!
  3766. {
  3767. delay(300);
  3768. while ( !(ts.tirqTouched() && ts.touched()) ) {;}
  3769. }
  3770.  
  3771.  
  3772.  
  3773. void SD_listFiles()
  3774. {
  3775. uint16_t y=0;
  3776. String s1;
  3777.  
  3778. TFT.fillScreen(NOIR);
  3779. TFT.setTextColor(BLANC, NOIR);
  3780. TFT.setFreeFont(FF0);
  3781. TFT.drawString("Liste des fichiers (en memoire SD)", 0, y); y+=30;
  3782.  
  3783.  
  3784. File root = SD.open("/");
  3785. File file = root.openNextFile();
  3786. while (file)
  3787. {
  3788. s1 = String(file.name());
  3789. TFT.setTextColor(VERT, NOIR);
  3790. TFT.drawString(s1, 0, y);
  3791.  
  3792. s1 = "size:";
  3793. TFT.setTextColor(BLANC, NOIR);
  3794. TFT.drawString(s1, 100, y);
  3795.  
  3796. s1 = file.size();
  3797. TFT.setTextColor(JAUNE, NOIR);
  3798. TFT.drawString(s1, 140, y);
  3799.  
  3800. y+=10;
  3801. file = root.openNextFile();
  3802. }
  3803. }
  3804.  
  3805.  
  3806.  
  3807. void SD_RAZ()
  3808. {
  3809. boolean valider = false; // <-- ecrire "= true" pour rendre l'effacement possible
  3810. // (évite tout effacement accidentel et donc perte de centaines de fréquences...)
  3811.  
  3812. if(valider == false)
  3813. {
  3814. TFT.fillScreen(NOIR);
  3815. TFT.setFreeFont(FM9);
  3816. TFT.drawString("FONCTION VOLONTAIREMENT", 50, 120);
  3817. TFT.drawString("INACTIVE", 50, 140);
  3818. TFT.drawString("VOIR LE CODE SOURCE", 50, 160);
  3819. TFT.drawString("void SD_RAZ()", 50, 180);
  3820. delay(3000);
  3821. init_affichages();
  3822. return;
  3823. }
  3824.  
  3825. SD.remove("FRQ_SW.txt");
  3826. SD.remove("FRQ_SW_PRST.txt");
  3827. SD.remove("FRQ_FM.txt");
  3828. SD.remove("FRQ_FM_PRST.txt");
  3829. SD.remove("FRQ_AIR.txt");
  3830. SD.remove("FRQ_AIR_PRST.txt");
  3831.  
  3832. Serial.println("fin RAZ SD");
  3833. }
  3834.  
  3835.  
  3836.  
  3837. void test_clic_bouton_LST()
  3838. {
  3839. uint16_t c1 = NOIR;
  3840. uint16_t c2 = VERT;
  3841.  
  3842. test_clic_boutons(&bt_LST );
  3843. if(bt_LST.cliked)
  3844. {
  3845. if (SDcardOk == false) { affi_message ( "SDcard absente", "...", "", "", "" ); return; }
  3846.  
  3847. bt_LST.cliked = false;
  3848. bt_LST.selected = false;
  3849. bt_LST.affiche( c1, 1);
  3850.  
  3851. SD_listFiles();
  3852. init_1_bouton(1, 300, 5, 15, 15, "OK", &bt_annuler);
  3853. attente_clic2();
  3854.  
  3855. TFT.fillScreen(NOIR);
  3856. groupe_SW.affiche_bloc("SW",0);
  3857. groupe_FM.affiche_bloc("FM",100);
  3858. groupe_AIR.affiche_bloc("AIR",200);
  3859. init_1_bouton(1, 300, 5, 15, 15, "OK", &bt_annuler);
  3860. attente_clic2();
  3861.  
  3862. mute = true;
  3863. Set_Mute(true); // fonction située dans le fichier 'driverTEF6686_628.h'
  3864. delay(50);
  3865. bt_mute.selected = true;
  3866. bt_mute.affiche(ROUGE, 1);
  3867. delay(500);
  3868. affi_deroulant("Liste codes PI RDS", "/RDS_codes_PI.lst");
  3869. retour_normal();
  3870. }
  3871. }
  3872.  
  3873.  
  3874.  
  3875. void test_clic_bouton_SD_write() // en SD, dans un des fichiers ("/FRQ_SW.txt" ...)
  3876. {
  3877. uint16_t c1 = GRIS_6;
  3878. uint16_t c2 = VERT;
  3879. String s1;
  3880.  
  3881. test_clic_boutons(&bt_SD_write );
  3882. if(bt_SD_write.cliked)
  3883. {
  3884.  
  3885. bt_SD_write.cliked=false;
  3886. bt_SD_write.selected=false;
  3887. bt_SD_write.affiche( GRIS_5, 1);
  3888.  
  3889. Serial.println("--------------------------------");
  3890. Serial.println("bouton_SD_write clic");
  3891.  
  3892. //attention à ne pas oublier ces < >
  3893. s1 = "<";
  3894. s1 += String(frequence); // // fréquence en cours
  3895. s1 += ">";
  3896.  
  3897. boolean ok = false;
  3898. if (bande_SW)
  3899. {
  3900. if (! groupe_SW.test_Frq_presente(frequence)) // test effectué sur le groupe en RAM
  3901. {
  3902. // AJOUTE la fréquence en fin d'une liste de fréquences. Travaille directement sur la mémoire SD
  3903. File file = SD.open("/FRQ_SW.txt", FILE_APPEND);
  3904. file.print(s1);
  3905. file.print('\n');
  3906. file.close(); // enregistre CE fichier en mémoire SD, sans toucher aux autres
  3907. delay(300);
  3908. ok = true;
  3909. }
  3910. }
  3911.  
  3912. if (bande_FM)
  3913. {
  3914. if (! groupe_FM.test_Frq_presente(frequence))
  3915. {
  3916. File file = SD.open("/FRQ_FM.txt", FILE_APPEND);
  3917. file.print(s1);
  3918. file.close();
  3919. delay(300);
  3920. ok = true;
  3921. }
  3922. }
  3923.  
  3924. if (bande_AIR)
  3925. {
  3926. if (! groupe_AIR.test_Frq_presente(frequence))
  3927. {
  3928. File file = SD.open("/FRQ_AIR.txt", FILE_APPEND);
  3929. file.print(s1);
  3930. file.close();
  3931. delay(300);
  3932. ok = true;
  3933. }
  3934. }
  3935.  
  3936. String s1, s2;
  3937. if (ok) {s1 = "Enregistrement OK"; s2 = ""; }
  3938. else {s1 = "Freq. deja presente"; s2 = "NOT SAVE";}
  3939. Serial.println(s1);
  3940.  
  3941. if (ok) {load_GRP_FREQ_SD();} // recharge les listes de fréquences depuis la SD pour être à jour
  3942.  
  3943. TFT.fillScreen(NOIR);
  3944. TFT.setTextColor(JAUNE, NOIR);
  3945. TFT.setFreeFont(FF1);
  3946. TFT.drawString(s1, 5, 40);
  3947. TFT.drawString(s2, 5, 60);
  3948. delay(1000);
  3949. retour_normal();
  3950. }
  3951. }
  3952.  
  3953.  
  3954.  
  3955. void test_clic_bt_erase_1F() // en SD
  3956. {
  3957. uint16_t c1 = GRIS_6;
  3958. uint16_t c2 = VERT;
  3959.  
  3960. test_clic_boutons(&bt_erase_1F );
  3961. if(bt_erase_1F.cliked)
  3962. {
  3963. bt_erase_1F.cliked = false;
  3964. bt_erase_1F.selected = false;
  3965. bt_erase_1F.affiche(c1, 1);
  3966.  
  3967. delay (100);
  3968. bt_erase_1F.cliked = false;
  3969. bt_erase_1F.selected = false;
  3970. bt_erase_1F.affiche(c2, 1); // fugitif
  3971.  
  3972. uint16_t F;
  3973.  
  3974. //todo: en SD
  3975.  
  3976. }
  3977. }
  3978.  
  3979.  
  3980. void test_clic_boutons_MODE() // FREQ - MEM
  3981. {
  3982. uint16_t c1 = NOIR;
  3983. uint16_t c2 = VERT;
  3984. uint16_t c3 = JAUNE;
  3985.  
  3986. bt_mode_FRQ.cliked = false;
  3987. bt_mode_MEM.cliked = false;
  3988.  
  3989. test_clic_boutons(&bt_mode_FRQ );
  3990. if (bt_mode_FRQ.cliked) // les boutons sont exclusifs
  3991. {
  3992. presetPad1.deselect_boutons();
  3993. mode_s = _FRQ;
  3994. affiche_index_frq();
  3995. bt_4.selected=true; // 100kHz
  3996. bt_4.affiche(c2, 1);
  3997. bt_mode_FRQ.selected = true;
  3998. bt_mode_MEM.selected = false;
  3999. affiche_frequence(frequence);
  4000. efface_numero_frq();
  4001. }
  4002.  
  4003. test_clic_boutons(&bt_mode_MEM );
  4004. if (bt_mode_MEM.cliked)
  4005. {
  4006. efface_index_frq();
  4007. mode_s = _MEM;
  4008. bt_mode_MEM.selected = true;
  4009. bt_mode_FRQ.selected = false;
  4010. affiche_frequence(frequence);
  4011. }
  4012.  
  4013. bt_mode_FRQ.affiche(c2, 2);
  4014. bt_mode_MEM.affiche(c3, 2);
  4015. init_boutons_Plus_Moins(); //ce qui va changer le symbole affiché en '-' et '+' ou '<' et '>' en fonction du 'mode_s'
  4016. if (mode_affi == NORMAL)
  4017. {
  4018. bt_moins.affiche(VERT ,1);
  4019. bt_plus.affiche(VERT ,1);
  4020. }
  4021.  
  4022. }
  4023.  
  4024.  
  4025. void test_clic_boutons_BANDE() // SW, FM, AIR, SCAN
  4026. {
  4027. uint16_t c1 = GRIS_5;
  4028. uint16_t c2 = VERT;
  4029.  
  4030. bt_SW.cliked = false;
  4031. bt_FM.cliked = false;
  4032. bt_AIR.cliked = false;
  4033.  
  4034. test_clic_boutons(&bt_SW );
  4035. if (bt_SW.cliked)
  4036. {
  4037. TFT.fillRect(x0_box_info1+2, y0_box_info1+1, 118, 12, NOIR); // efface
  4038. efface_box_entete2();
  4039. //Serial.println("bt_SW.cliked");
  4040. bt_SW.cliked = false;
  4041.  
  4042. groupe_actif = gSW;
  4043. bande_active = SW;
  4044. modulation_active = AM;
  4045. bt_SW.selected = true;
  4046. bt_FM.selected = false; // les boutons sont exclusifs
  4047. bt_AIR.selected = false;
  4048. bt_SCN.selected = false;
  4049.  
  4050. //clic_logiciel_bouton(&presetPad1.bt_preset[0]);
  4051. //traite_boutons_presetPad(0);
  4052.  
  4053. frequence = 15000; // 15MHz
  4054. Tune_Frequence(frequence);
  4055. affiche_frequence(frequence);
  4056.  
  4057. uint8_t nb_F = groupe_SW.nb_freq;
  4058. affiche_numero_frq(String(1), String(nb_F));
  4059. }
  4060.  
  4061.  
  4062. test_clic_boutons(&bt_FM );
  4063. if (bt_FM.cliked)
  4064. {
  4065. //Serial.println("bt_FM.cliked");
  4066. efface_box_entete2();
  4067. bt_FM.cliked = false;
  4068.  
  4069. groupe_actif = gFM;
  4070. bande_active = FM;
  4071. modulation_active = WFM;
  4072. bt_FM.selected = true;
  4073. bt_SW.selected = false;
  4074. bt_AIR.selected = false;
  4075. bt_SCN.selected = false;
  4076. affi_boutons_SW_FM_AIR_SCN();
  4077.  
  4078. //traite_boutons_presetPad(0);
  4079. frequence = presetPad1.bt_preset[0].frequence_FM;
  4080. Tune_Frequence(frequence);
  4081. affiche_frequence(frequence);
  4082. clic_logiciel_bouton(&presetPad1.bt_preset[0]);
  4083.  
  4084. uint8_t nb_F = groupe_FM.nb_freq;
  4085. affiche_numero_frq(String(1), String(nb_F));
  4086. }
  4087.  
  4088.  
  4089. test_clic_boutons(&bt_AIR );
  4090. if (bt_AIR.cliked)
  4091. {
  4092. TFT.fillRect(x0_box_info1+2, y0_box_info1+1, 118, 12, NOIR); // efface
  4093. efface_box_entete2();
  4094. //Serial.println("bt_AIR.cliked");
  4095. bt_AIR.cliked = false;
  4096.  
  4097. groupe_actif = gAIR;
  4098. bande_active = AIR;
  4099. modulation_active = AM;
  4100. bt_AIR.selected = true;
  4101. bt_SW.selected = false;
  4102. bt_FM.selected = false;
  4103. bt_SCN.selected = false;
  4104. affi_boutons_SW_FM_AIR_SCN();
  4105.  
  4106. frequence = 123500;
  4107. Tune_Frequence(frequence);
  4108. affiche_frequence(frequence);
  4109.  
  4110. //clic_logiciel_bouton(&presetPad1.bt_preset[0]);
  4111. //traite_boutons_presetPad(0);
  4112.  
  4113.  
  4114. uint8_t nb_F = groupe_AIR.nb_freq;
  4115. affiche_numero_frq(String(1), String(nb_F));
  4116. }
  4117.  
  4118.  
  4119. test_clic_boutons(&bt_SCN );
  4120. if (bt_SCN.cliked == true)
  4121. {
  4122. efface_box_entete2();
  4123. Serial.println("bt_SCN.cliked");
  4124. bt_SCN.cliked = false;
  4125.  
  4126. groupe_actif = gSCN;
  4127. bande_active = SCN;
  4128. bt_SCN.selected = true;
  4129. bt_SW.selected = false;
  4130. bt_FM.selected = false;
  4131. bt_AIR.selected = false;
  4132. affi_boutons_SW_FM_AIR_SCN();
  4133.  
  4134. presetPad1.deselect_boutons();
  4135.  
  4136. uint8_t nb_F = groupe_SCAN.nb_freq;
  4137. affiche_numero_frq(String(1), String(nb_F));
  4138. }
  4139.  
  4140. Serial.print("groupe actif = "); Serial.println(groupe_actif);
  4141.  
  4142. }
  4143.  
  4144.  
  4145. void test_clic_bouton_set() // bouton pour passer dans le mode d'écriture de la F en cours en SD
  4146. // L'écriture en question sera effectuée par la fonction 'traite_boutons_presetPad()'
  4147. {
  4148. test_clic_boutons(&bt_set);
  4149. if (bt_set.cliked)
  4150. {
  4151. bt_set.cliked = false;
  4152. vu_metre_actif = false;
  4153. TFT.fillRect(x0_box_info2, y0_box_info2, 140, 70, NOIR);
  4154.  
  4155. TFT.setTextColor(VERT, NOIR);
  4156. TFT.setFreeFont(FF0);
  4157. TFT.drawString("Cliquez sur un des 8 bt", x0_box_info2+2, y0_box_info2+2);
  4158. TFT.drawString("'preset' pour lui ", x0_box_info2+2, y0_box_info2+12);
  4159. TFT.drawString("attribuer la F en cours", x0_box_info2+2, y0_box_info2+22);
  4160.  
  4161. init_1_bouton(1, x0_box_info2+82, y0_box_info2+50, 50, 15, "annuler", &bt_annuler);
  4162. bt_annuler.affiche(BLANC, 1);
  4163.  
  4164. mode_affi = SET_F_PRESET; // ce qui modifie le comportement de la fonction 'traite_boutons_presetPad()'
  4165. Serial.println("mode_affi == SET_F_PRESET");
  4166.  
  4167. delay (100);
  4168. bt_set.selected = false;
  4169. bt_set.affiche(BLANC, 1);
  4170. }
  4171. }
  4172.  
  4173.  
  4174. void affi_bargraph(uint16_t x, uint16_t y, uint16_t dx, int16_t vi)
  4175. {
  4176. if(! quiet)
  4177. {
  4178. //TFT.fillRect(x, y, dx, 8, NOIR); // efface
  4179. if (valeur_bargraph < vi) {valeur_bargraph ++;} // pour déplassements progressifs
  4180. if (valeur_bargraph > vi) {valeur_bargraph --;} // pour déplassements progressifs
  4181.  
  4182. if(valeur_bargraph<0) {valeur_bargraph =0;}
  4183. if(valeur_bargraph > dx) {valeur_bargraph = dx;}
  4184. TFT.drawRect(x, y, dx, 5, couleur_traits);
  4185. //TFT.fillRect(x, y, valeur_bargraph, 5, JAUNE);
  4186. TFT.fillRect(x + valeur_bargraph, y, 1, 5, VERT); // affiche juste l'extrémité
  4187. TFT.fillRect(x + valeur_bargraph+1, y, 1, 5, NOIR); // efface juste l'extrémité +1
  4188. }
  4189. else
  4190. {
  4191. TFT.fillRect(x, y, dx, 5, couleur_fond_ecran); // efface le bargraph
  4192. }
  4193. }
  4194.  
  4195.  
  4196. void affiche_tension_batt(uint16_t x, uint16_t y, uint16_t dx, int8_t valeur) // valeur en %
  4197. {
  4198. uint16_t c1;
  4199. c1 = ROUGE;
  4200. if(valeur>30){c1 = ORANGE;}
  4201. if(valeur>50){c1 = JAUNE;}
  4202. if(valeur>70){c1 = VERT;}
  4203.  
  4204. uint32_t v2 = valeur * dx / 100;
  4205. TFT.fillRect(x-20, y, dx, 8, NOIR); // efface
  4206. efface_box_entete3();
  4207. if(v2<0) {valeur =0;}
  4208. if(v2 > dx) {v2 = dx;}
  4209. TFT.drawRect(x, y, dx, 5, couleur_traits);
  4210. TFT.fillRect(x, y, v2, 5, c1);
  4211.  
  4212. String s1 = String(valeur) +"%";
  4213. TFT.setTextColor(BLANC, NOIR);
  4214. TFT.setFreeFont(FF0);
  4215. TFT.drawString(s1, x-20, y);
  4216. TFT.drawString("bat", x + 10 , y+5);
  4217.  
  4218. TFT.drawRect(0, 0, 319, 240, couleur_traits); // cadre principal pourtour de l'écran
  4219. }
  4220.  
  4221.  
  4222. /*
  4223. void affiche_1_bargraph(uint16_t x, uint16_t y, uint16_t dx, int16_t valeur, uint16_t couleur)
  4224. {
  4225. TFT.fillRect(x, y, dx+40, 8, NOIR); // efface
  4226. TFT.drawString(String(valeur), x, y);
  4227.  
  4228. if(valeur<0) {valeur =0;}
  4229. if(valeur > dx) {valeur = dx;}
  4230. TFT.drawRect(x+40, y, dx, 5, couleur_traits);
  4231. TFT.drawRect(x+40, y, valeur, 5, couleur);
  4232. }
  4233.  
  4234. void affiche_bars_graph()
  4235. {
  4236. affiche_1_bargraph(170, 150, 100, level/10, VERT);
  4237. affiche_1_bargraph(170, 160, 100, usn, JAUNE);
  4238. affiche_1_bargraph(170, 170, 100, wam, BLEU_CLAIR);
  4239. affiche_1_bargraph(170, 180, 100, offset, BLANC);
  4240. }
  4241. */
  4242.  
  4243. String int_to_hex(uint16_t nb)
  4244. {
  4245. char symb[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
  4246. uint8_t A = (nb & 0b1111000000000000) >>12;
  4247. uint8_t B = (nb & 0b0000111100000000) >>8;
  4248. uint8_t C = (nb & 0b0000000011110000) >>4;
  4249. uint8_t D = (nb & 0b0000000000001111);
  4250. String s1 = String(symb[A]) + String(symb[B]) + String(symb[C]) + String(symb[D]) ;
  4251. return s1;
  4252. }
  4253.  
  4254.  
  4255.  
  4256. void traite_signal_RDS()
  4257. {
  4258. Get_RDS_Data(&status, &A_block, &B_block, &C_block, &D_block, &dec_error);
  4259. /*
  4260. A_Block always contains the 16-bit program identifier.
  4261. The first 11 bits (bits 15–5) of block 2 are also the same in all groups.
  4262.  
  4263. La Liste des codes RDS autorisés se trouve ici : https://www.csa.fr/maradiofm/radiords_tableau
  4264.  
  4265. Pour les autres blocks, voir :
  4266. https://en.wikipedia.org/wiki/Radio_Data_System
  4267. (c'est sans doute logique mais terriblement indigeste !!!)
  4268. */
  4269. char buffer1[64];
  4270. uint16_t nombre =0;
  4271. String s_recue, s1, s2, s3;
  4272.  
  4273. s_recue = int_to_hex(A_block); // exemple: 'F201' ; mis à jour par le 'Get_RDS_Data()'
  4274. if (s_recue == memo_s_recue) {return; } // puisque rien de nouveau à traiter
  4275. memo_s_recue = s_recue;
  4276.  
  4277. TFT.fillRect(x0_box_info1+2, y0_box_info1, 118, 16, NOIR); // efface (en bas à gauche)
  4278. TFT.setTextColor(BLEU_CLAIR, GRIS_6);
  4279. TFT.setFreeFont(FF0);
  4280.  
  4281. File file1 = SD.open("/RDS_codes_PI.lst", "r");
  4282. while (file1.available())
  4283. {
  4284. int nb_bytes = file1.readBytesUntil('\n', buffer1, sizeof(buffer1));
  4285. buffer1[nb_bytes] = 0; // zéro terminal afin d'obtenir un string
  4286. s1 = buffer1;
  4287.  
  4288. s2 = s1.substring(0, 4); // exemple: 'F218'
  4289. s3 = s1.substring(4); // la suite
  4290.  
  4291.  
  4292. if (s_recue == s2) // la station reçue figure dans la liste
  4293. {
  4294. TFT.setTextColor(JAUNE, GRIS_6);
  4295. TFT.drawString(s2, x0_box_info1+5, y0_box_info1 +4);
  4296.  
  4297. TFT.setTextColor(BLEU_CLAIR, GRIS_6);
  4298. TFT.drawString(s3, x0_box_info1+30, y0_box_info1 +4);
  4299.  
  4300. return; // on ne continue pas à boucler si trouvé
  4301. }
  4302. }
  4303. }
  4304.  
  4305.  
  4306.  
  4307. void affiche_force_signal()
  4308. {
  4309. //----------------------------------------------------------------------------------------------------------
  4310. // AFFICHE FORCE SIGNAL HF
  4311. compteur1 =0;
  4312.  
  4313. //float signal_sur_bruit = level;// - 1.5 * usn; // marche à peu près bien pour la FM.
  4314.  
  4315. float diff = level - position_aiguille;
  4316. if(diff > 30.0) {diff = 30.0;}
  4317. if(diff < -30.0) {diff = -30.0;} // évite une trop grande réaction au sortir du mode 'mute'
  4318. // supprime les tremblements de l'aiguille
  4319. position_aiguille += diff / 6.0;
  4320.  
  4321.  
  4322. //affi_bargraph(170, 90, 60, mod/2);
  4323.  
  4324. if ((mode_affi == NORMAL) && (! mute) && (! quiet))
  4325. {
  4326. plotAiguille(position_aiguille/6.0); // génère des parasites audibles !
  4327. }
  4328. if ((mode_affi == NORMAL) && (mute) )
  4329. {
  4330. //plotAiguille(0);
  4331. }
  4332. }
  4333.  
  4334.  
  4335. void loop()
  4336. {
  4337. if((mode_affi != SCAN_F) && (mode_affi != SCAN_M))// invalide les boutons situés derrière le panneau scan en modes SCAN
  4338. {
  4339. if (ts.tirqTouched() && ts.touched())
  4340. {
  4341. memo_y_touch = y_touch;
  4342. get_XY_touch();
  4343.  
  4344. test_clic_6_boutons_frq(); // 6 rectangles situés au dessus des gros chiffres de la fréquence
  4345. test_clic_bouton_mute();
  4346. //test_clic_bouton_SD_RAZ();
  4347. test_clic_bouton_SD_write();
  4348. test_clic_bouton_LST();
  4349. test_clic_bt_erase_1F();
  4350. uint8_t n_touch1 = numPad1.test_clic(); // pavé numérique
  4351. if (n_touch1 != 253) { traite_touches_pad(n_touch1); } // pavé numérique
  4352.  
  4353. test_clic_boutons_plus_moins(); // boutons '<' et '>'
  4354. test_clic_bouton_Sleep();
  4355. test_clic_bt_LED();
  4356. test_clic_bt_CAL(); // calibration de l'écran tactile
  4357. test_clic_bt_quiet();
  4358. test_clic_bouton_TEST();
  4359. test_clic_bouton_info();
  4360. test_clic_bt_capture(); // capture écran
  4361. test_clic_Bt_reset();
  4362. test_clic_Bt_SCAN(); // choix bande à scanner (SW - FM) et type FRQ ou AIR (puis déclenche le scan)
  4363. test_clic_boutons_MODE(); // FREQ / MEM (tout en haut à gauche des gros chiffres)
  4364. test_clic_boutons_BANDE(); // SW, FM, AIR, SC; (SC = SCAN)
  4365.  
  4366. uint8_t num_bouton = presetPad1.test_clic(); // 8 petits boutons carrés de présélection de 8 fréquences
  4367. if (num_bouton != 253) { traite_boutons_presetPad(num_bouton); }
  4368.  
  4369. test_clic_bouton_set(); // attribution de la fréquence en cours à un des 8 boutons preset.
  4370. test_clic_bt_annuler();
  4371.  
  4372. test_clic_bt_coul();
  4373. test_clic_bt_RST_affi();
  4374. }
  4375.  
  4376. // la limitation SW max = 28MHz est due au module TEF6686 lui-même
  4377. if (frequence >= 138000) {frequence = 138000;} //138 MHz limite à cause SW max = 28MHz et conv AirBand = 110 MHz
  4378. if (frequence < 1500) {frequence = 1500;} // 1.5 MHz
  4379.  
  4380. uint8_t module;
  4381. if(bande_active == FM) {module = 32;} else {module = 33;}
  4382. Get_Quality( module, &status, &level, &usn, &wam, &offset, &bandwidth, &mod, &snr );
  4383.  
  4384. affi_bargraph(170, 90, 60, mod/2);
  4385.  
  4386.  
  4387. if (compteur1 >= 20)
  4388. {
  4389. affiche_force_signal();
  4390.  
  4391. //----------------------------------------------------------------------------------------------------------
  4392. // AFFICHE TENSION BATTERIE
  4393. //----------------------------------------------------------------------------------------------------------
  4394. // voir la feuille de calcul 'Mesure de la tension de la batterie.ods' établie sur tests avec alim numérique
  4395. // voir aussi, sur le schéma, la valeur des résistances (diviseur analogique) sur l'entrée GPIO35 (analogPin = 35)
  4396. // Note: la valeur de la tension sur le pin GPIO35 ne doit jamais dépasser 3v3 (ce qui est lu = 4096)
  4397. int valeurLue;
  4398. valeurLue = analogRead(analogPin);
  4399. //Serial.print("valeurLue = "); Serial.println(valeurLue);
  4400. float pourcent = ((float)valeurLue - 2570.0) / 7.5;
  4401. if (pourcent > 100.0) {pourcent = 100.0;}
  4402. if (pourcent < 0.0) {pourcent = 0.0;}
  4403.  
  4404. //Serial.print("pourcent = "); Serial.println(pourcent);
  4405.  
  4406. // intégration
  4407. float diff2 = pourcent - valeur_affi;
  4408. if(diff2 > 10.0) {diff2 = 10.0;}
  4409. if(diff2 < -10.0) {diff2 = -10.0;} // évite une trop grande réaction au sortir du mode 'mute'
  4410. valeur_affi += diff2 / 10.0;
  4411.  
  4412. if ( abs(valeur_affi - memo_valeur_affi) > 1.5 ) // pour éviter trop d'affichages inutiles (et clignotements à l'écran)
  4413. {
  4414. affiche_tension_batt(270, 4, 46, (int8_t) valeur_affi);
  4415. memo_valeur_affi = valeur_affi;
  4416. }
  4417. }
  4418.  
  4419. if (compteur2 >= 100)
  4420. {
  4421. compteur2 =0;
  4422.  
  4423. if(bande_active == FM) {traite_signal_RDS();}
  4424. }
  4425.  
  4426. if (quiet == true)
  4427. {
  4428. affi_image_from_SD("/bmp565/montagne140x70.bmp", x0_vu_metre, y0_vu_metre);
  4429. attente_clic2();
  4430. // quiet (anti-parasites audio, surtout pour les stations faibles)
  4431. // inconvéniants: fige les affichages (vu_metre, bargraph signal audio...)
  4432. }
  4433. /*
  4434. if (compteur3 >= 1000)
  4435. {
  4436. // passe en mode quiet automatiquement, avec ses inconvéniants !
  4437. compteur3 =0;
  4438. bt_quiet.cliked = false;
  4439. bt_quiet.selected = true;
  4440. bt_quiet.affiche(VERT, 1);
  4441.  
  4442. attente_clic2(); // quiet (anti-parasites)
  4443.  
  4444. bt_quiet.cliked = false;
  4445. bt_quiet.selected = false;
  4446. bt_quiet.affiche(VERT, 1);
  4447. }
  4448. */
  4449. delay(5); // détermine la réactivité du bargraph
  4450. compteur1++;
  4451. compteur2++;
  4452. compteur3++;
  4453. }
  4454.  
  4455. }
  4456.  
  4457.  
  4458. /** ***************************************************************************************
  4459. CLASS TOUCH_BOUTON // affiche un nombre ou un petit texte dans un rectangle
  4460. ainsi que (en plus petit) deux valeurs supplémentaires, par ex: les valeurs mini et maxi
  4461. ********************************************************************************************/
  4462.  
  4463. // Constructeur
  4464. TOUCH_BOUTON::TOUCH_BOUTON()
  4465. {
  4466.  
  4467. }
  4468.  
  4469. // Constructeur
  4470. TOUCH_BOUTON_PRESET::TOUCH_BOUTON_PRESET()
  4471. {
  4472.  
  4473. }
  4474.  
  4475.  
  4476. // Constructeur
  4477. TOUCH_BOUTON_SW::TOUCH_BOUTON_SW()
  4478. {
  4479.  
  4480. }
  4481.  
  4482.  
  4483. void TOUCH_BOUTON::init(uint16_t x_i, uint16_t y_i, uint8_t dx_i, uint8_t dy_i, uint8_t dr_i, uint16_t couleur_i)
  4484. {
  4485. x0 = x_i;
  4486. y0 = y_i;
  4487. dx = dx_i;
  4488. dy = dy_i;
  4489. dr = dr_i;
  4490. couleur = couleur_i;
  4491.  
  4492. cliked = false;
  4493. selected = false;
  4494. }
  4495.  
  4496.  
  4497.  
  4498. void TOUCH_BOUTON::affiche(uint16_t coul_fill_select, uint8_t n_font)
  4499. {
  4500. uint16_t couleur_contour = GRIS_5;
  4501. uint16_t couleur_texte = BLANC;
  4502.  
  4503. if(selected)
  4504. {
  4505. TFT.fillRoundRect(x0, y0, dx, dy, dr, coul_fill_select);
  4506. TFT.setTextColor(NOIR);
  4507. }
  4508. else
  4509. {
  4510. TFT.fillRoundRect(x0, y0, dx, dy, dr, couleur); // efface
  4511. TFT.drawRoundRect(x0, y0, dx, dy, dr, couleur_contour); // retrace juste le contour
  4512. TFT.setTextColor(couleur_texte);
  4513. }
  4514.  
  4515. //FM9 FMB9 FSS9... voir le fichier FrSD_Fonts.h
  4516. if (n_font == 1) { TFT.setFreeFont(FF0);}
  4517. if (n_font == 2) { TFT.setFreeFont(FM9);}
  4518. if (n_font == 3) { TFT.setFreeFont(FMB9);}
  4519. if (n_font == 4) { TFT.setFreeFont(FSS9);}
  4520.  
  4521. TFT.drawString(label, x0+3, y0 + 2);
  4522. }
  4523.  
  4524.  
  4525. uint8_t TOUCH_BOUTON::read_dx()
  4526. {
  4527. return dx;
  4528. }
  4529.  
  4530.  
  4531. uint8_t TOUCH_BOUTON::read_dy()
  4532. {
  4533. return dy;
  4534. }
  4535.  
  4536. /** ***************************************************************************************
  4537. CLASS grid_PAD
  4538. ********************************************************************************************/
  4539. // Constructeur
  4540. GRID_PAD::GRID_PAD()
  4541. {
  4542.  
  4543. }
  4544.  
  4545.  
  4546. void GRID_PAD::init(uint16_t xi, uint16_t yi)
  4547. {
  4548. x0 = xi;
  4549. y0 = yi;
  4550. uint16_t x, y;
  4551.  
  4552.  
  4553. x = x0+2;
  4554. y = y0+1;
  4555.  
  4556. for(uint8_t n =1; n <= nb_t; n++)
  4557. {
  4558. bt_grid[n].init(x, y, dxt, dyt, 3, n * 100);
  4559. bt_grid[n].label="";
  4560. //bt_grid[n].affiche(BLEU, 1);
  4561. x += dxt+1;
  4562. if (x > (x0 + nb_bt_x * dxt)) {x = x0+2; y += dyt+1; }
  4563. }
  4564. }
  4565.  
  4566.  
  4567. void GRID_PAD::affiche()
  4568. {
  4569. for(uint8_t n =1; n <= nb_t; n++)
  4570. {
  4571. bt_grid[n].affiche(BLEU, 1);
  4572. }
  4573. }
  4574.  
  4575.  
  4576. void GRID_PAD::set_couleurs() // F = facteur d'assombrissement
  4577. {
  4578. /*
  4579. voir la page:
  4580. https://rgbcolorpicker.com/565
  4581. qui permet de reconfigurer les couleurs RGB565 (5+6+5 = 16 bits) très simplement
  4582. */
  4583. uint16_t c565i, c565i2;
  4584. uint8_t R, G, B;
  4585. int16_t j, k;
  4586.  
  4587.  
  4588. // les deux premières lignes couleurs arc-en-ciel
  4589. k=-16;
  4590. uint8_t F=1;
  4591. for(uint8_t n=0; n<32; n++)
  4592. {
  4593. j=30*(32-n);
  4594. c565i = couleurs_aec[2*j] | couleurs_aec[2*j+1]<<8;
  4595.  
  4596. RGB565_to_888(c565i, &R, &G, &B);
  4597. R /= F;
  4598. G /= F;
  4599. B /= F;
  4600. c565i2 = Color_To_565(R, G, B);
  4601. if((k>=0) && (k<16)) {bt_grid[k].couleur = c565i2;}
  4602. k++;
  4603. }
  4604.  
  4605. // les lignes 3 et 4 couleurs plus sombres
  4606. k=0;
  4607. F=3;
  4608. for(uint8_t n=0; n<32; n++)
  4609. {
  4610. j=30*(32-n);
  4611. c565i = couleurs_aec[2*j] | couleurs_aec[2*j+1]<<8;
  4612.  
  4613. RGB565_to_888(c565i, &R, &G, &B);
  4614. R /= F;
  4615. G /= F;
  4616. B /= F;
  4617. c565i2 = Color_To_565(R, G, B);
  4618. if((k>=16) && (k<32)) {bt_grid[k].couleur = c565i2;}
  4619. k++;
  4620. }
  4621.  
  4622. bt_grid[16].couleur = 49174; // violet
  4623.  
  4624. //bt_grid[25].couleur = 0b1111100000000000; // R
  4625. //bt_grid[26].couleur = 0b0000011111100000; // V
  4626. //bt_grid[27].couleur = 0b0000000000011111; // B
  4627. //bt_grid[28].couleur = 0xFFFF;
  4628. //bt_grid[29].couleur = 0;
  4629.  
  4630. bt_grid[32].couleur = GRIS_4;
  4631. bt_grid[32].label="X";
  4632. }
  4633.  
  4634.  
  4635.  
  4636. uint8_t GRID_PAD::test_clic()
  4637. {
  4638. if ( (( x_touch > x0) && (x_touch < (x0 + dxt*nb_bt_x +20))) && (( y_touch > y0) && (y_touch < (y0 + dyt*nb_bt_y +10))))
  4639. {
  4640. uint8_t num_bouton =255;
  4641.  
  4642. for(uint8_t n = 0; n<nb_t; n++)
  4643. {
  4644. test_clic_boutons(&bt_grid[n] );
  4645. if(bt_grid[n].cliked)
  4646. {
  4647. num_bouton = n;
  4648. }
  4649. }
  4650.  
  4651. delay(100);
  4652. return num_bouton;
  4653. }
  4654. return 253;
  4655. }
  4656.  
  4657.  
  4658. /** ***************************************************************************************
  4659. CLASS NUMPAD
  4660. ********************************************************************************************/
  4661. // Constructeur
  4662. NUM_PAD::NUM_PAD()
  4663. {
  4664.  
  4665. }
  4666.  
  4667.  
  4668. void NUM_PAD::init(uint16_t xi, uint16_t yi, boolean fond) // si fond =false, ne resessine que les boutons
  4669. {
  4670. x0 = xi;
  4671. y0 = yi;
  4672. uint16_t x, y;
  4673. uint8_t dxt = 25; // taille x d'une touche
  4674. uint8_t dyt = 23; // taille y d'une touche
  4675.  
  4676. if(fond == true) {TFT.fillRect(x0, y0, 3*dxt +6, 4*dyt +7, NOIR);}
  4677.  
  4678. if(fond == true) {TFT.fillRect(x0, y0, 3*dxt +6, 4*dyt +7, NOIR);}
  4679.  
  4680. uint16_t c1 = GRIS_5;
  4681. uint16_t c2 = JAUNE;
  4682.  
  4683. x = x0+2;
  4684. y = y0+2;
  4685.  
  4686. for(uint8_t n =1; n<10; n++)
  4687. {
  4688. bt_pad[n].init(x, y, dxt, dyt, 3, GRIS_5);
  4689. bt_pad[n].label=String(n);
  4690. bt_pad[n].affiche(c2, 2);
  4691. x += dxt+1;
  4692. if (x > (x0 + 3*dxt)) {x = x0+2; y += dyt+1; }
  4693. }
  4694. bt_pad[0].init(x, y, dxt, dyt, 3, GRIS_5); bt_pad[0].label="0"; bt_pad[0].affiche(c2, 2); x += dxt+1;
  4695. bt_point.init(x, y, dxt, dyt, 3, GRIS_5); bt_point.label="."; bt_point.affiche(c2, 2);
  4696.  
  4697. x += dxt+1;
  4698. bt_ok.init(x, y, dxt, dyt, 3, GRIS_5); bt_ok.label="ok";
  4699. bt_ok.affiche(c2, 1);
  4700. }
  4701.  
  4702.  
  4703. uint8_t NUM_PAD::test_clic()
  4704. {
  4705. // zone des boutons du clavier
  4706. if ( (( x_touch > x0) && (x_touch < x0 + 100)) && (( y_touch > y0) && (y_touch < y0 + 130)))
  4707. {
  4708. uint8_t num_touche =0;
  4709.  
  4710. for(uint8_t n = 0; n<10; n++)
  4711. {
  4712. test_clic_boutons(&bt_pad[n] ); if(bt_pad[n].cliked) {num_touche=n; n_appui ++;}
  4713. }
  4714.  
  4715. test_clic_boutons(&bt_point ); if(bt_point.cliked) {num_touche=254; } // bouton "."
  4716. test_clic_boutons(&bt_ok ); if(bt_ok.cliked) {num_touche=255; n_appui ++;} // bouton "ok"
  4717. delay(100);
  4718. init(x0, y0, false); // 'false' évite le clignotement lorsqu'on repeint le fond noir
  4719.  
  4720. return num_touche;
  4721. }
  4722. return 253;
  4723. }
  4724.  
  4725. /** ***************************************************************************************
  4726. CLASS PRESET_PAD
  4727. ********************************************************************************************/
  4728.  
  4729. // Constructeur
  4730. PRESET_PAD::PRESET_PAD()
  4731. {
  4732.  
  4733. }
  4734.  
  4735.  
  4736. void PRESET_PAD::init(uint16_t xi, uint16_t yi)
  4737. {
  4738. x0 = xi;
  4739. y0 = yi;
  4740.  
  4741. uint16_t c1 = GRIS_5;
  4742. uint16_t c2 = JAUNE;
  4743.  
  4744. uint16_t x2, y2;
  4745. x2 = x0;
  4746. y2= y0;
  4747.  
  4748. for(uint8_t n=0; n<8; n++)
  4749. {
  4750. bt_preset[n].init(x2, y2, 15, 15, 3, GRIS_5);
  4751. bt_preset[n].label=String(n+1);
  4752. if(mode_affi == COUL) {c1 = bt_preset[n].couleur;}
  4753. bt_preset[n].affiche(c2, 1);
  4754. x2 += 20;
  4755. }
  4756. }
  4757.  
  4758.  
  4759. uint8_t PRESET_PAD::read_dx()
  4760. {
  4761. return dx;
  4762. }
  4763.  
  4764.  
  4765. uint8_t PRESET_PAD::read_dy()
  4766. {
  4767. return dy;
  4768. }
  4769.  
  4770.  
  4771.  
  4772. void PRESET_PAD::set_frequences_PRST() // lit les fréquences en SD et les attribue à chaque bouton PRESET
  4773. {
  4774. Serial.println("void PRESET_PAD::set_frequences()");
  4775.  
  4776. uint8_t n=0;
  4777.  
  4778. read_FRQ_File(SD, "/FRQ_SW_PRST.txt", "SW");
  4779. read_FRQ_File(SD, "/FRQ_FM_PRST.txt", "FM");
  4780. read_FRQ_File(SD, "/FRQ_AIR_PRST.txt", "AIR");
  4781. }
  4782.  
  4783.  
  4784. void PRESET_PAD::set_couleurs()
  4785. {
  4786. /*
  4787. voir la page:
  4788. https://rgbcolorpicker.com/565
  4789. qui permet de reconfigurer les couleurs RGB565 (5+6+5 = 16 bits) très simplement
  4790. */
  4791.  
  4792. bt_preset[0].couleur = 28672; // rouge sombre
  4793. bt_preset[1].couleur = 43584; // orange
  4794. bt_preset[2].couleur = 832; // vert
  4795. bt_preset[3].couleur = 14407; // violet
  4796. bt_preset[4].couleur = 58157; // rose
  4797. bt_preset[5].couleur = 975; // cyan
  4798. bt_preset[6].couleur = 21819; // bleu ciel
  4799. bt_preset[7].couleur = 12; // bleu marine
  4800. }
  4801.  
  4802.  
  4803.  
  4804. void PRESET_PAD::deselect_boutons()
  4805. {
  4806. uint16_t c1 = GRIS_5;
  4807. uint16_t c2 = JAUNE;
  4808.  
  4809. for(int n =0; n<8; n++)
  4810. {
  4811. bt_preset[n].selected=false;
  4812. bt_preset[n].cliked=false;
  4813. bt_preset[n].affiche(c2, 1);
  4814. }
  4815. }
  4816.  
  4817.  
  4818. uint8_t PRESET_PAD::test_clic()
  4819. {
  4820. if ( (( x_touch > x0) && (x_touch < (x0+155))) && (( y_touch > y0) && (y_touch < (y0+15))))
  4821. {
  4822. uint8_t num_bouton =0;
  4823. for(uint8_t n=0; n<8; n++)
  4824. {
  4825. test_clic_boutons(&bt_preset[n]);
  4826. if(bt_preset[n].cliked)
  4827. {
  4828. deselect_boutons(); // les autres
  4829. bt_preset[n].selected =true; // pour l'affichage de celui-ci
  4830. bt_preset[n].affiche(JAUNE, 1);
  4831. num_bouton = n;
  4832. //Serial.print("BB num_bouton= "); Serial.println(num_bouton);
  4833. }
  4834. }
  4835. delay(300);
  4836. return num_bouton;
  4837. }
  4838. return 253;
  4839. }
  4840.  
  4841.  
  4842.  
  4843. /** ***************************************************************************************
  4844. CLASS SW_PAD
  4845. ********************************************************************************************/
  4846. // Constructeur
  4847. SW_PAD::SW_PAD()
  4848. {
  4849.  
  4850. }
  4851.  
  4852.  
  4853. void SW_PAD::init(uint16_t xi, uint16_t yi)
  4854. {
  4855. x0 = xi;
  4856. y0 = yi;
  4857.  
  4858. uint16_t x2, y2;
  4859. x2 = x0;
  4860. y2 = y0;
  4861.  
  4862. set_frequences_SW();
  4863.  
  4864. for(uint8_t n=0; n<14; n++)
  4865. {
  4866. bt_SW[n].init(x2, y2, 30, 12, 3, GRIS_5);
  4867. String sA = String(bt_SW[n].freq_A);
  4868. String sB = String(bt_SW[n].freq_B);
  4869. bt_SW[n].affiche(JAUNE, 1);
  4870. TFT.setTextColor(CYAN, NOIR);
  4871. TFT.setFreeFont(FF0);
  4872. TFT.drawString(sA + "..", x2+35, y2);
  4873. TFT.drawString(sB, x2+80, y2);
  4874. if (n==0) {TFT.drawString("kHz", x2+110, y0);}
  4875. y2 += 16;
  4876. }
  4877. }
  4878.  
  4879.  
  4880. void SW_PAD::set_frequences_SW()
  4881. {
  4882. // bandes plus larges que les 'bandes officielles de radiodiffusion' afin de couvrir tt les frq sans trous
  4883. bt_SW[0].freq_A=2300; bt_SW[0].freq_B=3200; bt_SW[0].lambda=120;
  4884. bt_SW[1].freq_A=3200; bt_SW[1].freq_B=3900; bt_SW[1].lambda=90;
  4885. bt_SW[2].freq_A=3900; bt_SW[2].freq_B=4750; bt_SW[2].lambda=75;
  4886. bt_SW[3].freq_A=4750; bt_SW[3].freq_B=5950; bt_SW[3].lambda=60;
  4887. bt_SW[4].freq_A=5950; bt_SW[4].freq_B=7100; bt_SW[4].lambda=49;
  4888. bt_SW[5].freq_A=7100; bt_SW[5].freq_B=9500; bt_SW[5].lambda=41;
  4889. bt_SW[6].freq_A=9500; bt_SW[6].freq_B=11650; bt_SW[6].lambda=31;
  4890. bt_SW[7].freq_A=11650; bt_SW[7].freq_B=13600; bt_SW[7].lambda=25;
  4891. bt_SW[8].freq_A=13600; bt_SW[8].freq_B=15100; bt_SW[8].lambda=22;
  4892. bt_SW[9].freq_A=15100; bt_SW[9].freq_B=17550; bt_SW[9].lambda=19;
  4893. bt_SW[10].freq_A=17550; bt_SW[10].freq_B=18900; bt_SW[10].lambda=16;
  4894. bt_SW[11].freq_A=18900; bt_SW[11].freq_B=21450; bt_SW[11].lambda=15;
  4895. bt_SW[12].freq_A=21450; bt_SW[12].freq_B=25670; bt_SW[12].lambda=13;
  4896. bt_SW[13].freq_A=25670; bt_SW[13].freq_B=27900; bt_SW[13].lambda=11;
  4897.  
  4898. for(int n =0; n<=13; n++)
  4899. {
  4900. bt_SW[n].label = String(bt_SW[n].lambda) + "m";
  4901. }
  4902. }
  4903.  
  4904.  
  4905. uint8_t SW_PAD::test_clic()
  4906. {
  4907. if ( (( x_touch > x0) && (x_touch < (x0+40))) && (( y_touch > y0) && (y_touch < 240)))
  4908. {
  4909. uint8_t num_bouton =0;
  4910. for(uint8_t n=0; n<=13; n++)
  4911. {
  4912. test_clic_boutons(&bt_SW[n]);
  4913. if(bt_SW[n].cliked)
  4914. {
  4915. deselect_boutons(); // les autres
  4916. bt_SW[n].selected =true; // pour l'affichage de celui-ci
  4917. bt_SW[n].affiche(JAUNE, 1);
  4918. num_bouton = n;
  4919. }
  4920. }
  4921. delay(300);
  4922. return num_bouton;
  4923. }
  4924. return 253;
  4925. }
  4926.  
  4927.  
  4928. void SW_PAD::deselect_boutons()
  4929. {
  4930. uint16_t c1 = GRIS_5;
  4931. uint16_t c2 = JAUNE;
  4932.  
  4933. for(int n =0; n<=13; n++)
  4934. {
  4935. bt_SW[n].selected=false;
  4936. bt_SW[n].cliked=false;
  4937. bt_SW[n].affiche(c2, 1);
  4938. }
  4939. }
  4940.  
  4941. /** ***************************************************************************************
  4942. CLASS GROUPE_FREQUENCES // objet image d'un bloc mémoire en SD
  4943. permet diverses manipulations en RAM (tri...) sans toucher à la SD (évite usure mémoire flash)
  4944. ********************************************************************************************/
  4945.  
  4946. // Constructeur
  4947. GROUPE_FREQUENCES::GROUPE_FREQUENCES()
  4948. {
  4949.  
  4950. }
  4951.  
  4952.  
  4953. void GROUPE_FREQUENCES::RAZ() // en RAM uniquement
  4954. {
  4955. for(int n=0; n<100; n++)
  4956. {
  4957. G_freq[n]=0;
  4958. }
  4959. nb_freq = 0;
  4960. }
  4961.  
  4962.  
  4963. void GROUPE_FREQUENCES::load_bloc() // depuis la SDcard --> vers groupe en RAM
  4964. {
  4965. Serial.println("--------------------------");
  4966. Serial.println("GROUPE_FREQUENCES::load_bloc()");
  4967. Serial.print("Reading file: "); Serial.println(filename);
  4968. File file = SD.open(filename);
  4969. if (!file ) { Serial.println("failed to open file for reading"); return; }
  4970. String s;
  4971. uint8_t n =0;
  4972.  
  4973. while (file.available())
  4974. {
  4975. char c;
  4976. c = char(file.read());
  4977. if ((c !='<') && (c !='>')) {s += c;}
  4978. if(c=='>')
  4979. {
  4980. uint32_t frq;
  4981. frq = s.toInt();
  4982. Serial.println(frq);
  4983. s="";
  4984. G_freq[n] = frq;
  4985. n++;
  4986. }
  4987. }
  4988. file.close();
  4989. Serial.print(n); Serial.println(" frequences");
  4990. }
  4991.  
  4992.  
  4993. boolean GROUPE_FREQUENCES::test_Frq_presente(uint32_t F_i) // travaille en RAM
  4994. {
  4995. Serial.println("--------------------------");
  4996. Serial.println("test_Frq_presente()");
  4997. uint16_t n =0;
  4998. uint16_t adresse_lue;
  4999. uint32_t valeur_lue;
  5000. boolean ok = false;
  5001. for (n=0; n<100; n++)
  5002. {
  5003. valeur_lue = G_freq[n];
  5004. if (valeur_lue == F_i) {return true;} // si F est présente
  5005. }
  5006. return false; // si F non présente
  5007. }
  5008.  
  5009.  
  5010. void GROUPE_FREQUENCES::tri_bloc()
  5011. {
  5012. Serial.println("--------------------------");
  5013. Serial.println("tri_block()");
  5014. // tri par bulles
  5015.  
  5016. uint32_t F1=0, F2=0;
  5017. uint32_t Fi;
  5018. uint16_t i_max = 100;
  5019. uint16_t p_max = 100;
  5020.  
  5021.  
  5022. for(uint16_t p=0; p<p_max; p++)
  5023. {
  5024. //for(int n=0; n<i_max-1; n++)
  5025. uint16_t n =0;
  5026. while(n<i_max-1)
  5027. {
  5028. F1=G_freq[n];
  5029. F2=G_freq[n+1];
  5030.  
  5031. if(F1 > F2)
  5032. {
  5033. Fi = G_freq[n];
  5034. G_freq[n] = G_freq[n+1];
  5035. G_freq[n+1] = Fi;
  5036. }
  5037. n++;
  5038. }
  5039. }
  5040.  
  5041. // ici les freq sont dédoublées !!!!!!!!!!!!
  5042.  
  5043. // compte le nombre de fréquences != 0
  5044. uint16_t nombre =0;
  5045. for(uint16_t n = 0; n<100; n++ )
  5046. {
  5047. F1 = G_freq[n];
  5048. if(F1 != 0) { nombre++;}
  5049. }
  5050. nb_freq = nombre;
  5051.  
  5052. // recherche première fréquence non nulle
  5053. uint16_t n2=0;
  5054. F1 =0;
  5055. while ((F1==0) && (n2<100))
  5056. {
  5057. F1=G_freq[n2];
  5058. n2++;
  5059. }
  5060. adr_1ere_frq = n2-1; // 1ere F non nulle
  5061.  
  5062. }
  5063.  
  5064.  
  5065. void GROUPE_FREQUENCES::bloc_to_serial()
  5066. {
  5067. // pour tests, avec CuteCom sous Linux
  5068. // travaille en RAM uniquement, sans toucher aux fichiers SD
  5069. Serial.println("--------------------------");
  5070. Serial.println("bloc_to_serial()");
  5071. uint32_t valeur_lue;
  5072. uint16_t nombre =0;
  5073. for(uint16_t n = 0; n<100; n++ )
  5074. {
  5075. valeur_lue = G_freq[n];
  5076. if(valeur_lue != 0) // n'affiche pas les emplacements vides
  5077. {
  5078. nombre++;
  5079. Serial.println(valeur_lue);
  5080. }
  5081. }
  5082. Serial.print(nombre); Serial.println(" frequences");
  5083. //Serial.print("1ere Frq= "); Serial.println(G_freq[adr_1ere_frq]);
  5084. }
  5085.  
  5086.  
  5087. // voir la fonction 'void affi_liste()// des aérodromes' du ND.ino
  5088. void GROUPE_FREQUENCES::affiche_bloc(String nom, uint16_t x)
  5089. {
  5090. // travaille en RAM uniquement, sans toucher aux fichiers SD
  5091. uint32_t valeur_lue;
  5092. uint16_t nombre =0;
  5093. uint16_t y;
  5094. String s1;
  5095.  
  5096. TFT.setTextColor(BLANC, NOIR);
  5097. TFT.setFreeFont(FF0);
  5098. TFT.drawString(nom, x, 0);
  5099. y=20;
  5100. for(uint16_t n = 0; n<100; n++ )
  5101. {
  5102. valeur_lue = G_freq[n];
  5103. if(valeur_lue != 0) // n'affiche pas les emplacements vides
  5104. {
  5105. nombre++;
  5106.  
  5107. s1 = String(nombre);
  5108. TFT.setTextColor(BLEU, NOIR);
  5109. TFT.drawString(s1, x, y);
  5110.  
  5111. s1 = valeur_lue;
  5112. TFT.setTextColor(BLANC, NOIR);
  5113. TFT.drawString(s1, x+20, y);
  5114.  
  5115. y+=10;
  5116. }
  5117. }
  5118. Serial.print(nombre); Serial.println(" frequences");
  5119.  
  5120. }
  5121.  
  5122.  
  5123.  
  5124. void GROUPE_FREQUENCES::add_frq(uint32_t Fi) // en RAM uniquement
  5125. {
  5126. Serial.println("--------------------------");
  5127. if (nb_freq >= 100) {return;}
  5128. Serial.println("GROUPE_FREQUENCES::add_frq()");
  5129.  
  5130. if (test_Frq_presente(Fi) == true)
  5131. {
  5132. Serial.println("Frq presente, pas d'ajout");
  5133. return;
  5134. }
  5135. tri_bloc(); // les F nulles se retrouvent en haut
  5136. Serial.print("Ajout frequence: "); Serial.println(Fi);
  5137. G_freq[0] = Fi; // la nouvelle fréquence est placée en haut
  5138. nb_freq++;
  5139. tri_bloc(); // la nouvelle fréquence se retrouve rangée dans l'ordre de F croissantes
  5140. }
  5141.  
  5142.  
  5143.  
  5144. void GROUPE_FREQUENCES::erase_1_freq(uint32_t Fi) // en RAM
  5145. {
  5146. Serial.println("--------------------------");
  5147. Serial.println("GROUPE_FREQUENCES::erase_1_freq()");
  5148. uint32_t valeur_lue;
  5149. for(int n=0; n<100; n++)
  5150. {
  5151. valeur_lue = G_freq[n];
  5152. if(valeur_lue == Fi)
  5153. {
  5154. G_freq[n]=0;
  5155. }
  5156. }
  5157. tri_bloc();
  5158. }
  5159.  
  5160.  

Mises à jour quasi-quotidiennes...

12 Le fichier d'entêtes main.h

Le fichier main.h :
CODE SOURCE en C++
  1. #include <Arduino.h>
  2.  
  3. // pour obtenir ces valeurs simplement, ouvrir une image bmp565 320x240 (ok) avec l'éditeur Hexa ImHex (Linux)
  4. // sélectionner la partie entête, puis File/export/Text Formatted Bytes/C++ Array
  5. // ce qui est vachement pratique !
  6. const uint8_t bmp565_header[] PROGMEM =
  7. {
  8. 0x42, 0x4D, 0x8A, 0x58, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8A, 0x00, 0x00, 0x00, 0x7C, 0x00,
  9. 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x03, 0x00,
  10. 0x00, 0x00, 0x00, 0x58, 0x02, 0x00, 0x23, 0x2E, 0x00, 0x00, 0x23, 0x2E, 0x00, 0x00, 0x00, 0x00,
  11. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x1F, 0x00,
  12. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x47, 0x52, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  13. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  14. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  15. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
  16. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  17. };
  18. // soit 138 octets
  19.  
  20.  
  21. /** ***********************************************************************************
  22. CLASS
  23. ***************************************************************************************/
  24.  
  25. class TOUCH_BOUTON
  26. {
  27. protected:
  28. uint8_t dx;
  29. uint8_t dy;
  30. uint8_t dr; // rayon de courbure des angles
  31.  
  32. public:
  33. uint16_t x0;
  34. uint16_t y0;
  35. uint16_t couleur;
  36.  
  37. String label;
  38. boolean cliked;
  39. boolean selected;
  40.  
  41. uint8_t read_dx();
  42. uint8_t read_dy();
  43.  
  44. TOUCH_BOUTON(); // constructeur
  45.  
  46. void init(uint16_t x_i, uint16_t y_i, uint8_t dx_i, uint8_t dy_i, uint8_t dr_i, uint16_t couleur_i);
  47. void affiche(uint16_t coul_fill_select, uint8_t n_font);
  48.  
  49. private:
  50.  
  51. };
  52.  
  53.  
  54.  
  55. class TOUCH_BOUTON_PRESET : public TOUCH_BOUTON
  56. {
  57. public:
  58. uint32_t frequence_SW; // 4 octets
  59. uint32_t frequence_FM; // 4 octets
  60. uint32_t frequence_AIR;// 4 octets
  61. // String nom;
  62.  
  63. TOUCH_BOUTON_PRESET(); // constructeur
  64.  
  65. private:
  66. };
  67.  
  68.  
  69.  
  70. class TOUCH_BOUTON_SW : public TOUCH_BOUTON
  71. {
  72. public:
  73. uint32_t freq_A; // 4 octets - fréquence de départ
  74. uint32_t freq_B; // fréquence de fin de la bande, sans trou
  75. uint16_t lambda; // longueur d'onde en m
  76.  
  77. TOUCH_BOUTON_SW(); // constructeur
  78.  
  79. private:
  80. };
  81.  
  82.  
  83.  
  84. /** ***************************************************************************************
  85. CLASS PRESET_PAD // objet 8 touches d'accès rapide à 8 fréquences favorites adns chaque gamme
  86. ********************************************************************************************/
  87. class PRESET_PAD
  88. {
  89. protected:
  90. uint8_t dx;
  91. uint8_t dy;
  92.  
  93. public:
  94. uint8_t x0;
  95. uint8_t y0;
  96.  
  97. TOUCH_BOUTON_PRESET bt_preset[8];
  98.  
  99. PRESET_PAD(); // constructeur
  100.  
  101. void init(uint16_t x0, uint16_t y0);
  102. uint8_t read_dx();
  103. uint8_t read_dy();
  104. void set_frequences_PRST();
  105. void set_couleurs();
  106.  
  107. void deselect_boutons();
  108. uint8_t test_clic();
  109. //void traite_presetPad(uint8_t n_touch);
  110.  
  111. private:
  112.  
  113. };
  114.  
  115. /** ***************************************************************************************
  116. CLASS SW_PAD // objet 14 boutons de sélection de bandes SW (ondes courtes)
  117. ********************************************************************************************/
  118. class SW_PAD
  119. {
  120. protected:
  121. uint8_t dx;
  122. uint8_t dy;
  123.  
  124. public:
  125. uint8_t x0;
  126. uint8_t y0;
  127.  
  128. TOUCH_BOUTON_SW bt_SW[14];
  129.  
  130. SW_PAD(); // constructeur
  131.  
  132. void init(uint16_t x0, uint16_t y0);
  133. void set_frequences_SW();
  134.  
  135. void deselect_boutons();
  136. uint8_t test_clic();
  137.  
  138. private:
  139.  
  140. };
  141.  
  142. /** ***************************************************************************************
  143. CLASS NUM_PAD // objet clavier numérique
  144. ********************************************************************************************/
  145.  
  146. class NUM_PAD
  147. {
  148. protected:
  149.  
  150.  
  151. public:
  152. uint8_t x0;
  153. uint8_t y0;
  154.  
  155. TOUCH_BOUTON bt_pad[10];
  156.  
  157. TOUCH_BOUTON bt_point;
  158. TOUCH_BOUTON bt_ok;
  159.  
  160. NUM_PAD(); // constructeur
  161.  
  162. void init(uint16_t x0, uint16_t y0, boolean fond);
  163. uint8_t test_clic();
  164.  
  165. private:
  166.  
  167. };
  168.  
  169. /** ***************************************************************************************
  170. CLASS GRID_PAD // objet grille de boutons
  171. ********************************************************************************************/
  172.  
  173. class GRID_PAD
  174. {
  175. protected:
  176.  
  177.  
  178. public:
  179. uint8_t x0;
  180. uint8_t y0;
  181. uint8_t dxt = 16; // taille x d'un bouton
  182. uint8_t dyt = 16; // taille y d'un bouton
  183. static const uint8_t nb_bt_x = 8; // nombre de boutons x
  184. static const uint8_t nb_bt_y = 4; // nombre de boutons y
  185. static const uint8_t nb_t = nb_bt_x * nb_bt_y; //total nombre de boutons
  186.  
  187. TOUCH_BOUTON bt_grid[nb_t];
  188.  
  189. GRID_PAD(); // constructeur
  190.  
  191. void init(uint16_t x0, uint16_t y0);
  192. void set_couleurs();
  193. void affiche();
  194. uint8_t test_clic();
  195.  
  196. private:
  197.  
  198. };
  199.  
  200.  
  201.  
  202.  
  203. /** ***************************************************************************************
  204. CLASS GROUPE_FREQUENCES // objet image d'un bloc mémoire en SD
  205. permet diverses manipulations en RAM (tri...) sans toucher à la mémoire SD (qui est en mémoire flash)
  206. ********************************************************************************************/
  207. class GROUPE_FREQUENCES
  208. {
  209. public:
  210. uint32_t G_freq[100];
  211. uint16_t adr_1ere_frq; // après un tri les F=0 se retrouvent en haut de liste. La 1ere F se retrouve donc bien plus bas
  212. uint16_t nb_freq; // nombre de fréquences !=0 enregistées
  213. uint16_t num_F_actuelle;
  214. String filename; // du fichier en mémoire SD (par exemple "/FRQ_FM.txt")
  215.  
  216. GROUPE_FREQUENCES(); // constructeur
  217.  
  218. void RAZ();
  219. void load_bloc(); // depuis SD
  220. void bloc_to_serial(); // pour tests
  221. void affiche_bloc(String nom, uint16_t x);
  222. void tri_bloc(); // par valeur numérique des fréquences
  223. void add_frq(uint32_t Fi);
  224. void erase_1_freq(uint32_t Fi);
  225.  
  226. boolean test_Frq_presente(uint32_t F_i);
  227.  
  228. private:
  229.  
  230. };
  231.  
  232.  
  233. // ************************************************************************************
  234.  
  235.  
  236. void setup();
  237. void loop();
  238. void printTouchToDisplay();
  239. void init_sprites();
  240. void efface_box_entete1();
  241. void efface_box_entete2();
  242. void efface_box_entete3();
  243. void init_affichages();
  244. void affi_image_from_SD(String filename, uint16_t x0, uint16_t y0);
  245. void write_fichier_params();
  246. void load_GRP_FREQ_SD();
  247. String read_line_params(uint16_t line_num);
  248. int32_t extract_params(String ligne, String label);
  249. void affiche_unit(String s);
  250. void affiche_band(String s);
  251. void affiche_numero_frq(String s1, String s2);
  252. void efface_box_entete2();
  253. void efface_box_entete3();
  254. //void affiche_box_choix_couleur();
  255. //void affi_valeurs_RGB();
  256. void affiche_box_FRQ(uint16_t couleur);
  257. void affiche_box_presets();
  258. void deselect_boutons_presets();
  259. void traite_boutons_presetPad(uint8_t n_bt);
  260. void affi_message(String L1, String L2, String L3, String L4, String L5);
  261. void affiche_box_GROUPE();
  262. void efface_box_GROUPE();
  263. void affiche_box_SD();
  264. void affiche_box_FRQ(uint16_t couleur);
  265. void affiche_frequence(uint32_t frq); // en kHz
  266. void affiche_index_frq();
  267. void affiche_force_signal();
  268. void clic_logiciel_bouton(TOUCH_BOUTON *bouton_i);
  269. void dessine_VuMetre();
  270. void init_box_info();
  271. void test_clic_boutons_BANDE();
  272. void test_clic_bouton_TEST();
  273. void test_clic_bt_capture();
  274. void read_FRQ_File(); // en mémoire SD
  275. void scan_frq(uint32_t freq_iA, uint32_t freq_iB, String band_name);
  276. void attente_clic();
  277. void attente_clic2();
  278. void Set_Volume(int v);
  279. void get_XY_touch();
  280. void TS_calibrate();
  281. void liste_codes_PI_RDS();
  282. void retour_normal();

13 documents

Code source complet en C++
Version du code source adaptée à l’éditeur VScode/PlatformIO


14 -

Liens...
Pour me joindre : silicium628@free.fr

441