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

Voir le lien plus bas.

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 boitier

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 SDcarte qui dépasse à peine du boitier.

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

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 bmp656 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 s;
  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.  
  64. TOUCH_BOUTON_PRESET(); // constructeur
  65.  
  66. private:
  67. };
  68.  
  69.  
  70.  
  71.  
  72.  
  73.  
  74. /** ***************************************************************************************
  75. CLASS PRESET_PAD // objet 8 touches d'accès rapide à 8 fréquences favorites adns chaque gamme
  76. ********************************************************************************************/
  77. class PRESET_PAD
  78. {
  79. protected:
  80. uint8_t dx;
  81. uint8_t dy;
  82.  
  83. public:
  84. uint8_t x0;
  85. uint8_t y0;
  86.  
  87. TOUCH_BOUTON_PRESET bt_preset[8];
  88.  
  89. PRESET_PAD(); // constructeur
  90.  
  91. void init(uint16_t x0, uint16_t y0);
  92. uint8_t read_dx();
  93. uint8_t read_dy();
  94. void set_frequences_PRST();
  95. void set_couleurs();
  96.  
  97. void deselect_boutons();
  98. uint8_t test_clic();
  99. //void traite_presetPad(uint8_t n_touch);
  100.  
  101. private:
  102.  
  103. };
  104.  
  105. /** ***************************************************************************************
  106. CLASS NUM_PAD // objet clavier numérique
  107. ********************************************************************************************/
  108.  
  109. class NUM_PAD
  110. {
  111. protected:
  112.  
  113.  
  114. public:
  115. uint8_t x0;
  116. uint8_t y0;
  117.  
  118. TOUCH_BOUTON bt_pad[10];
  119.  
  120. TOUCH_BOUTON bt_point;
  121. TOUCH_BOUTON bt_ok;
  122.  
  123. NUM_PAD(); // constructeur
  124.  
  125. void init(uint16_t x0, uint16_t y0, boolean fond);
  126. uint8_t test_clic();
  127.  
  128. private:
  129.  
  130. };
  131.  
  132. /** ***************************************************************************************
  133. CLASS GRID_PAD // objet grille de boutons
  134. ********************************************************************************************/
  135.  
  136. class GRID_PAD
  137. {
  138. protected:
  139.  
  140.  
  141. public:
  142. uint8_t x0;
  143. uint8_t y0;
  144. uint8_t dxt = 16; // taille x d'un bouton
  145. uint8_t dyt = 16; // taille y d'un bouton
  146. static const uint8_t nb_bt_x = 8; // nombre de boutons x
  147. static const uint8_t nb_bt_y = 4; // nombre de boutons y
  148. static const uint8_t nb_t = nb_bt_x * nb_bt_y; //total nombre de boutons
  149.  
  150. TOUCH_BOUTON bt_grid[nb_t];
  151.  
  152. GRID_PAD(); // constructeur
  153.  
  154. void init(uint16_t x0, uint16_t y0);
  155. void set_couleurs();
  156. void affiche();
  157. uint8_t test_clic();
  158.  
  159. private:
  160.  
  161. };
  162.  
  163.  
  164.  
  165.  
  166. /** ***************************************************************************************
  167. CLASS GROUPE_FREQUENCES // objet image d'un bloc mémoire en SD
  168. permet diverses manipulations en RAM (tri...) sans toucher à la mémoire SD (qui est en mémoire flash)
  169. ********************************************************************************************/
  170. class GROUPE_FREQUENCES
  171. {
  172. public:
  173. uint32_t G_freq[100];
  174. 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
  175. uint16_t nb_freq; // nombre de fréquences !=0 enregistées
  176. uint16_t num_F_actuelle;
  177. String filename; // du fichier en mémoire SD (par exemple "/FRQ_FM.txt")
  178.  
  179. GROUPE_FREQUENCES(); // constructeur
  180.  
  181. void RAZ();
  182. void load_bloc(); // depuis SD
  183. void bloc_to_serial(); // pour tests
  184. void affiche_bloc(String nom, uint16_t x);
  185. void tri_bloc(); // par valeur numérique des fréquences
  186. void add_frq(uint32_t Fi);
  187. void erase_1_freq(uint32_t Fi);
  188.  
  189. boolean test_Frq_presente(uint32_t F_i);
  190.  
  191. private:
  192.  
  193. };
  194.  
  195.  
  196. // ************************************************************************************
  197.  
  198.  
  199. void setup();
  200. void loop();
  201. void printTouchToDisplay();
  202. void init_sprites();
  203. void init_affichages();
  204. void affi_image_from_SD(String filename, uint16_t x0, uint16_t y0);
  205. void write_fichier_params();
  206. void load_GRP_FREQ_SD();
  207. String read_line_params(uint16_t line_num);
  208. int32_t extract_params(String ligne, String label);
  209. void affiche_unit(String s);
  210. void affiche_band(String s);
  211. void affiche_numero_frq(String s1, String s2);
  212. void efface_box_entete2();
  213. void efface_box_entete3();
  214. //void affiche_box_choix_couleur();
  215. //void affi_valeurs_RGB();
  216. void affiche_box_FRQ(uint16_t couleur);
  217. void affiche_box_presets();
  218. void deselect_boutons_presets();
  219. void traite_boutons_presetPad(uint8_t n_bt);
  220. void affiche_box_GROUPE();
  221. void efface_box_GROUPE();
  222. void affiche_box_boutons_scan();
  223. void affiche_box_SD();
  224. void affiche_box_FRQ(uint16_t couleur);
  225. void affiche_frequence(uint32_t frq); // en kHz
  226. void affiche_index_frq();
  227. void affiche_force_signal();
  228. void clic_logiciel_bouton(TOUCH_BOUTON *bouton_i);
  229. void dessine_VuMetre();
  230. void init_box_info();
  231. void test_clic_boutons_BANDE();
  232. void test_clic_bouton_TEST();
  233. void test_clic_bt_capture();
  234. void read_FRQ_File(); // en mémoire SD
  235. void scan_frq();
  236. void attente_clic();
  237. void attente_clic2();
  238.  
  239. //void Tune_Frequence_FM(uint16_t F);
  240. void Set_Volume(int v);
  241. void get_XY_touch();
  242. void TS_calibrate();
  243. void liste_codes_PI_RDS();
  244. 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

269