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

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 read_FRQ_File(); // en mémoire SD
  274. void scan_frq(uint32_t freq_iA, uint32_t freq_iB, String band_name);
  275. void attente_clic();
  276. void attente_clic2();
  277. void Set_Volume(int v);
  278. void get_XY_touch();
  279. void TS_calibrate();
  280. void liste_codes_PI_RDS();
  281. 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

447