Récepteur radio à TEF6686 et carte CYD

Ecran tactile. Utilisation simple. Code source extrêmement simple pour VisualCode & PlatformIO; Je suis reparti directement du PDF de NPX. Bandes SW, FM, aviation civile.

1 Description

On trouve sur Internet de nombreuses réalisations basées sur ce module récepteur TEF6686.Certaines réalisations sont commerciales, d'autres pas. Toutefois elles reprennent la plupart du temps le code source très complet et performant de PE5PVB disponible sur github.

Je me suis donc penché dans un premier temps sur ce code source. Et là.. Panique ! Des centaines de conditions "if then else" imbriquées rendant la compréhension très compliquée, du moins pour moi. Je ne critique pas ce code, je dis juste qu'il ne me convient pas.

Je suis donc reparti de zéro : le document "User_Manual_TEF6686.pdf" de NXP Semiconductors. Bon d'accord il est caviardé d'un grand "CONFIDENTIAL" en travers des 100 pages, mais vu qu'il est largement divulgué sur Internet... Et puis le fait de comprendre comment ça marche leur fera sans doute vendre des modules... Sachant que ledit module est déjà présent dans des milliers d'autoradios.

Mon code source fait environ 180 ko contre environ 9 Mo pour certains autres plus complets.

Pour ma part, j'ai permis l'accès de toutes les fonctions de gestion de fréquences avec l'écran tactile de la carte CYD, le plus simplement possible :
  • Choix d'une station parmis 8 près enregistrées ("presets") dans le code source.
  • Saisie de la fréquence directement par le pavé numérique.
  • Mise en mémoire EEPROM de la fréquence en cours (100 freq pour SW, 100 freq pour FM, et 100 freq pour la bande aviation).
  • Sélection des station en EEPROM par les boutons (+) et (-).
  • Sélection de la bande de fréquence par trois boutons SW, FM, AIR.
  • Modification de la fréquence en sélectionnant le digit par les petits boutons situés au dessus des chiffres, puis boutons (+) et (+).
  • Fonctions "Mute" (pour répondre au téléphone...) et "Sleep".. Cette fonction Sleep réduit la consommation de la carte CYD à quelques uA et réduit aussi le bruit HF de la carte, tout en laissant fonctionner le module. Pour réveiller l'ESP32 il faut reseter. (à voir...)
  • Vu-mètre du niveau de la porteuse HF, et bar-graphe sur le signal BF.
  • Choix de la couleur du fond d'écran : parmi 8 présets ou en ajustant manuellement les composantes R, G, et B.
Bandes de réception :
  • SW : 1500kHz .. 28 MHz
  • FM : 88 MHz .. 108 MHz
  • AIR: 108 MHz .. 138 MHz (avec convertisseur 110 MHz en entrée antenne)
Remarque : 138 MHz = 28 + 110 MHz. Pour aller plus haut, il faut utiliser un autre convertisseur (120 MHz...) et modifier le code (affichage) en conséquence... Les limites des fréquences sont celles imposées par le module TEF6686 lui même. Mais je compte bien ne pas en rester là, et étudier un autre module...

2 Le schéma :

La carte ESP32 Cheap Yellow Display Board (CYD) est celle sérigraphiée ESP-322432S028 avec un afficheur 2.8 pouces 320x240PX; C'est la plus courante. Il en existe d'autre modèles pour lesquels il faudrait modifier cetaines parties du code source...

3 Le module TEF6686 de chez MPX

.

4 Le module ampli BF

Voir le lien pls bas.

5 Les mini Haut Parleurs

Voir le lien plus bas...

6 Fichier source main.cpp :

CODE SOURCE en C++
  1. /*
  2. Radio TEF6686 perso
  3.  
  4. pour ESP32 Wroom + afficheur 2.8" TFT 240x320
  5. pour la carte CYD (Cheap Yellow Display)
  6. par Silicium628
  7.  
  8. */
  9.  
  10. /* ************************************************************************************
  11. CONCERNANT L'AFFICHAGE TFT
  12.  
  13. à placer dans le fichier User_Setup.h ( dans ~/Arduino/libraries/TFT_eSPI/ ):
  14. #define ILI9341_2_DRIVER
  15.  
  16. ****************************************************************************/
  17.  
  18. #include <Arduino.h>
  19. #include "main.h"
  20. #include "constantes_628.h"
  21. #include "DSP_INIT_628.h"
  22. #include "driverTEF6686_628.h"
  23.  
  24. #include <Free_Fonts.h>
  25.  
  26. #include "FS.h"
  27. #include "SD.h"
  28. #include "Wire.h"
  29.  
  30. #include <stdint.h>
  31. #include "TFT_eSPI.h" // Hardware-specific library
  32. #include "SPI.h"
  33. #include "Free_Fonts.h"
  34. #include "Digit_Font.h"
  35. #include <XPT2046_Touchscreen.h>
  36.  
  37. #include <EEPROM.h>
  38.  
  39. // #define _SD_CARD // commenter cette ligne pour utiliser une SDcard; décommenter pour utiliser le Touchscreen
  40.  
  41.  
  42. #define SPI_READ_FREQUENCY 16000000
  43.  
  44. // mem presets[EE_PRESETS_CNT];
  45.  
  46. #define EEPROM_SIZE 100+1200
  47. #define EEPROM_adrs_couleur 0 // 2 octets pour un uint16_t
  48. #define EEPROM_adrs_freq 2 // 4 octets pour un uint32_t
  49. #define EEPROM_adrs_mode 6 // 1 octet pour un uint8_t
  50.  
  51. // 100 premiers bytes réservés pour sauvegarder diverses variables (Frq en cours par exemple...)
  52. // reste 1200 bytes
  53. // chaque fréquence est un uint_32 = 4 bytes
  54. // 1200/4 = 300 fréquences mémorisée, c.a.d 3 bandes (SW, FM, AIR) de 100 freq chaque
  55. // Remarque : il y a largement la possibikité d'en prévoir beaucoup plus !!
  56.  
  57. #define bande_SW (frequence > 1500) && (frequence < 28000)
  58. #define bande_interdite1 (frequence > 28000) && (frequence < 88000)
  59. #define bande_interdite2 (frequence > 108000) && (frequence < 118000)
  60. #define bande_FM (frequence >= 88000) && (frequence < 108000)
  61. #define bande_AIR (frequence >= 118000) && (frequence < 138000)
  62.  
  63.  
  64. // XPT2046_Touchscreen // commenter cette ligne pour utiliser la fontion 'write_TFT_on_SDcard()'
  65. #define XPT2046_IRQ 36
  66. #define XPT2046_MOSI 32
  67. #define XPT2046_MISO 39
  68. #define XPT2046_CLK 25
  69. #define XPT2046_CS 33
  70.  
  71. //sur le connecteur CN1 de la carte CYD sérigraphiée 'ESP32-2432S028';
  72. //attention: ces valeurs ne sont pas celles par défaut pour SDA et SCL
  73. const int GPIO_SDA = 27;
  74. const int GPIO_SCL = 22;
  75.  
  76. #define High_16bto8b(a) ((uint8_t)((a) >> 8))
  77. #define Low_16bto8b(a) ((uint8_t)(a ))
  78. #define Convert8bto16b(a) ((uint16_t)(((uint16_t)(*(a))) << 8 |((uint16_t)(*(a+1)))))
  79.  
  80.  
  81. String version = "12.3";
  82.  
  83. SPIClass mySpi = SPIClass(VSPI);
  84. XPT2046_Touchscreen ts(XPT2046_CS, XPT2046_IRQ);
  85.  
  86. TFT_eSPI TFT = TFT_eSPI(); // Configurer le fichier User_Setup.h de la bibliothèque TFT_eSPI au préalable
  87. TFT_eSprite sprite_frq = TFT_eSprite(&TFT);
  88. //TFT_eSprite sprite_unit = TFT_eSprite(&TFT);
  89.  
  90.  
  91. // pour afficheur TFT
  92. const int _DX = 320;
  93. const int _DY = 240;
  94.  
  95.  
  96. float raddeg = M_PI/180.0;
  97. float deg_to_rad = 2.0 * M_PI /360.0;
  98.  
  99. //***************************************************************************
  100. //char var_array32[10];// 10 char + zero terminal - pour envoi par WiFi (because 2^32 -1 = 4294967295 -> 10 caractères)
  101. // =====================================================================
  102.  
  103.  
  104.  
  105.  
  106. TFT_eSprite Sprite_frq = TFT_eSprite(&TFT);
  107. // la def de 'TFT_eSprite' se trouve dans ~/Arduino/libraries/TFT_eSPI/Extensions/Sprite.h
  108.  
  109. //TFT_eSPI::loadFont(FREQFONT.h);
  110.  
  111. uint16_t compteur1 = 0;
  112. uint16_t compteur2 = 0;
  113. uint16_t compteur3 = 0;
  114. uint16_t compteur4 = 0;
  115. uint8_t SDcardOk=0;
  116. uint8_t do_wr_ecran_on_sd=0;
  117.  
  118. uint32_t frequence=1000;
  119. uint32_t saut_freq;
  120. uint32_t image_EE[300]; // permet le tri en RAM des fréquences sans toucher à l'EEPROM
  121.  
  122. GROUPE_FREQUENCES groupe_SW;
  123. GROUPE_FREQUENCES groupe_FM;
  124. GROUPE_FREQUENCES groupe_AIR;
  125.  
  126. String frequence_txt = "";
  127.  
  128. TOUCH_BOUTON bt_sleep;
  129.  
  130. TOUCH_BOUTON bt_mode_FRQ, bt_mode_MEM;
  131. TOUCH_BOUTON bt_plus, bt_moins;
  132. TOUCH_BOUTON bt_EE_RAZ, bt_EE_write, bt_EE_read;
  133. TOUCH_BOUTON bt_1, bt_2, bt_3, bt_4, bt_5, bt_6; // au dessus des chiffres de la fréquence
  134.  
  135. // --- boutons choix couleur-------
  136. TOUCH_BOUTON bt_affi_box_couleurs;
  137. TOUCH_BOUTON bt_R_plus, bt_R_moins;
  138. TOUCH_BOUTON bt_G_plus, bt_G_moins;
  139. TOUCH_BOUTON bt_B_plus, bt_B_moins;
  140. TOUCH_BOUTON bt_RST_affi;
  141. TOUCH_BOUTON bt_close1;
  142. TOUCH_BOUTON bt_coul_to_EEPROM;
  143.  
  144. TOUCH_BOUTON bt_test;
  145.  
  146. // ---------- numPad ------------
  147. TOUCH_BOUTON bt_num0, bt_num1, bt_num2, bt_num3, bt_num4, bt_num5, bt_num6, bt_num7, bt_num8, bt_num9;
  148. //TOUCH_BOUTON numPad[] = {bt_num0, bt_num1, bt_num2, bt_num3, bt_num4, bt_num5, bt_num6, bt_num7, bt_num8, bt_num9 };
  149.  
  150. NUM_PAD numPad1;
  151.  
  152.  
  153. //TOUCH_BOUTON bt_point, bt_ok;
  154. // -------------------------------
  155. TOUCH_BOUTON bt_SW, bt_FM, bt_AIR;
  156. TOUCH_BOUTON bt_mute;
  157.  
  158. TOUCH_BOUTON_PRESET bt_station1, bt_station2, bt_station3, bt_station4, bt_station5, bt_station6, bt_station7, bt_station8;
  159.  
  160.  
  161. boolean mute = false;
  162.  
  163. enum MODE_AFFI {COUL, VUM}; // couleur, vu-metre
  164. MODE_AFFI mode_affi = VUM;
  165.  
  166. //enum MODE_SELECT {FRQ, MEM};
  167.  
  168. #define _FRQ 0
  169. #define _MEM 1
  170. uint8_t mode_s;
  171.  
  172. enum BANDE {SW, FM, AIR};
  173. BANDE bande_active = FM;
  174.  
  175. uint16_t FRQ_x0 = 50;
  176. uint16_t FRQ_y0 = 30;
  177.  
  178. uint16_t x0_box_EEPROM = 0;
  179. uint16_t y0_box_EEPROM = 135;
  180.  
  181. uint16_t x0_box_PRESET =2;
  182. uint16_t y0_box_PRESET =87;
  183.  
  184. uint16_t x0_box_BANDE = 205; // SW - FM - AIR
  185. uint16_t y0_box_BANDE = 115;
  186.  
  187. uint16_t x0_numPad = 70;
  188. uint16_t y0_numPad = 117;
  189.  
  190. uint16_t x0_vu_metre = 170;
  191. uint16_t y0_vu_metre = 145;
  192.  
  193. uint16_t x0_box_info = 70;
  194. uint16_t y0_box_info = 218;
  195.  
  196. uint16_t x0_choix_couleur = 170;
  197. uint16_t y0_choix_couleur= 145;
  198.  
  199. uint8_t n_appui = 0; // incrémenté à chaque appui sur une touche du numPad numérique
  200. uint32_t total_saisi =0;
  201.  
  202. uint16_t x_touch, y_touch;
  203.  
  204. uint16_t status;
  205. int16_t level;
  206. uint16_t usn;
  207. uint16_t wam;
  208. int16_t offset;
  209. uint16_t bandwidth;
  210. uint16_t mod;
  211. int8_t snr;
  212.  
  213. uint16_t A_block;
  214. uint16_t B_block;
  215. uint16_t C_block;
  216. uint16_t D_block;
  217. uint16_t dec_error;
  218.  
  219. float position_aiguille = 0; // vu-metre
  220.  
  221.  
  222. uint16_t couleur_traits = GRIS_5;
  223. uint16_t JAUNE_chiffres = 65504;
  224. uint16_t VERT_chiffres = 2016;
  225.  
  226. uint8_t cR = 0;
  227. uint8_t cG = 0;
  228. uint8_t cB = 0;
  229. uint16_t couleur_fond_ecran = 0;
  230.  
  231.  
  232. float degTOrad(float angle)
  233. {
  234. return (angle * M_PI / 180.0);
  235. }
  236.  
  237.  
  238. uint8_t decToBcd( int val )
  239. {
  240. return (uint8_t) ((val / 10 * 16) + (val % 10));
  241. }
  242.  
  243.  
  244. uint16_t Color_To_565(uint8_t r, uint8_t g, uint8_t b)
  245. {
  246. return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3);
  247. }
  248.  
  249.  
  250. void RGB565_to_888(uint16_t color565, uint8_t *R, uint8_t *G, uint8_t *B)
  251. {
  252. *R=(color565 & 0xF800) >> 8;
  253. *G=(color565 & 0x7E0) >> 3;
  254. *B=(color565 & 0x1F) << 3 ;
  255.  
  256. }
  257.  
  258.  
  259. /** ***********************************************************************************
  260. CAPTURE D'ECRAN vers SDcard
  261. **************************************************************************************
  262.  
  263. ATTENTION : cette fonction est simultanément incompatible avec la fonction tactile (TOUCHSCREEN) de l'afficheur
  264. pour des raisons d'attribution des bus spi.(il n'y a que deux bus SPI personnalisés DISPONIBLES sur
  265. les 4 de l'ESP32 (2 sont à usage interne),
  266. il en manque donc un troisième !)
  267.  
  268. SCREEN SPI : (tel que défini dans le fichier User_Setup.h)
  269. TFT_MISO GPIO 12 // don't define this pin when using Touch and SD Card on the CYD
  270. TFT_MOSI GPIO 13
  271. TFT_SCLK GPIO 14
  272. TFT_CS GPIO 15 // Chip select control pin
  273. TFT_DC GPIO 2 // Data Command control pin
  274. TFT_RST GPIO 4 // Reset pin (could connect to RST pin)
  275. TFT_RST -1 // Set TFT_RST to -1 if display RESET is connected to ESP32 board RST
  276.  
  277. TOUCHSCREEN SPI :
  278. IRQ (XPT2046_IRQ) GPIO 36
  279. MOSI (XPT2046_MOSI) GPIO 32
  280. MISO (XPT2046_MISO) GPIO 39
  281. CLK (XPT2046_CLK) GPIO 25
  282. CS (XPT2046_CS) GPIO 33
  283.  
  284. MicoSD card SPI :
  285. MISO GPIO 19
  286. MOSI GPIO 23
  287. SCK GPIO 18
  288. CS GPIO 5
  289.  
  290. Il est possible de partager un même bus SPI entre plusieurs composants, (one master and multi slaves)
  291. mais ce n'est pas ce qui a été fait par les concepteurs de la CYD.
  292. Les deux bus internes sont utilisés, il n'en reste plus de disponible.
  293.  
  294. voir l'URL très simple(!) suivante :
  295. https://medium.com/@androidcrypto/how-to-use-touch-and-sd-card-at-the-same-time-on-an-esp32-cheap-yellow-display-cyd-45fa55d01ffe
  296.  
  297. */
  298.  
  299.  
  300. void init_SDcard()
  301. {
  302. Serial.println("init_SDcard()");
  303.  
  304.  
  305. if(!SD.begin())
  306. {
  307. Serial.println("Card Mount Failed");
  308. delay (1000);
  309. return;
  310. }
  311.  
  312. uint8_t cardType = SD.cardType();
  313.  
  314. if(cardType == CARD_NONE)
  315. {
  316. Serial.println("No SDcard");
  317. delay (1000);
  318. return;
  319. }
  320.  
  321. SDcardOk=1;
  322.  
  323. Serial.print("SDcard Type: ");
  324. if(cardType == CARD_SD) { Serial.println("SDSC"); }
  325. else if(cardType == CARD_SDHC) { Serial.println("SDHC"); }
  326.  
  327. uint32_t cardSize = SD.cardSize() / (1024 * 1024);
  328. String s1=(String)cardSize + " GB";
  329. Serial.print("SDcard size: ");
  330. Serial.println(s1);
  331.  
  332. delay (1000);
  333.  
  334. Serial.println("FIN init_SDcard()");
  335. }
  336.  
  337.  
  338.  
  339. // Fonction optimisée pour la carte CYD 320x240px avec la library 'TFT_eSPI'
  340. // ne convient PAS pour les ESP32 Wroom + afficheur 3.5" TFT 480x320
  341. void write_TFT_on_SDcard() // enregistre image bmp 320x240 RGB888
  342. {
  343. do_wr_ecran_on_sd =0;
  344. if (SDcardOk==0) {return;}
  345. int32_t x, y;
  346. uint16_t color565;
  347.  
  348. uint8_t octet_A;
  349. uint8_t octet_B;
  350.  
  351. if( ! SD.exists("/bmp/320x240_565.bmp")) {return;}
  352. File File1 = SD.open("/bmp/320x240_565.bmp", FILE_WRITE); // ouverture du fichier binaire (vierge) en écriture
  353. if (File1)
  354. {
  355. /*
  356. Les images en couleurs réelles BMP888 utilisent 24 bits par pixel:
  357. Il faut 3 octets pour coder chaque pixel, en respectant l'ordre de l'alternance bleu, vert et rouge.
  358. */
  359. uint16_t bmp_offset = 138;
  360. File1.seek(bmp_offset);
  361.  
  362. TFT.setFreeFont(FF0);
  363. TFT.setTextSize(1);
  364. TFT.setTextColor(JAUNE, NOIR);
  365.  
  366. for (y=240; y>0; y--)
  367. {
  368. for (x=0; x<320; x++)
  369. {
  370. color565=TFT.readPixel(x, y); // BBBBBrrr rrrVVVVV
  371.  
  372. octet_B = (color565 & 0b1111111100000000) >> 8;
  373. octet_A = (color565 & 0b0000000011111111);
  374.  
  375. //octet_A =0b11111000; octet_B =0b00000000 // ok tout bleu
  376. //octet_A =0b00000111; octet_B =0b11100000; // ok tout rouge
  377. //octet_A =0b00000000; octet_B =0b00011111; // ok tout vert
  378.  
  379. File1.write(octet_A);
  380. File1.write(octet_B);
  381. }
  382. String s1=String(y/10); TFT.drawString(s1, 170, 115); // affiche compte à rebour
  383. }
  384.  
  385. File1.close(); // referme le fichier
  386. TFT.fillRect(170, 115, 20, 8, GRIS_2); // efface le compte à rebour
  387. }
  388. }
  389. // ***********************************************************************************************************
  390.  
  391.  
  392. void affiche_index_frq() // 6 petits boutons juste au dessus de chaque chiffre pour indiquer celui à modifier
  393. {
  394. int x = FRQ_x0 +15;
  395. int y = FRQ_y0 - 5;
  396. uint16_t c1 = NOIR;
  397. uint16_t c2 = VERT;
  398.  
  399. bt_1.init(x, y, 20, 5, 0); bt_1.affiche(c1, c2, 1); x+=31;
  400. bt_2.init(x, y, 20, 5, 0); bt_2.affiche(c1, c2, 1); x+=31;
  401. bt_3.init(x, y, 20, 5, 0); bt_3.affiche(c1, c2, 1); x+=46;
  402. bt_4.init(x, y, 20, 5, 0); bt_4.affiche(c1, c2, 1); x+=31;
  403. bt_5.init(x, y, 20, 5, 0); bt_5.affiche(c1, c2, 1); x+=31;
  404. bt_6.init(x, y, 20, 5, 0); bt_6.affiche(c1, c2, 1);
  405. }
  406.  
  407.  
  408. void init_boutons_Plus_Moins()// boutons '+' et '-'
  409. {
  410. int x0 = 240;
  411. int y0 = 90;
  412.  
  413. uint16_t c1 = GRIS_6;
  414. uint16_t c2 = JAUNE;
  415.  
  416. bt_moins.init(x0, y0, 30, 20, 3);
  417. bt_moins.cliked = false;
  418. bt_moins.s="-";
  419. bt_moins.affiche(c1, c2 ,3);
  420.  
  421. bt_plus.init(x0+35, y0, 30, 20, 3);
  422. bt_plus.cliked = false;
  423. bt_plus.s="+";
  424. bt_plus.affiche(c1, c2 ,3);
  425.  
  426.  
  427. }
  428.  
  429. // bt_SW
  430. // bt_FM
  431. // bt_AIR
  432.  
  433.  
  434. void init_boutons_BANDE() // (SW - FM - AIR)
  435. {
  436. TFT.setFreeFont(FF0);
  437. bt_SW.init(x0_box_BANDE+4, y0_box_BANDE+5, 30, 15, 3);
  438. bt_SW.cliked = false;
  439. bt_SW.selected = false;
  440. bt_SW.s="SW";
  441. bt_SW.affiche(GRIS_6, NOIR, 1);
  442.  
  443. bt_FM.init(x0_box_BANDE+37, y0_box_BANDE+5, 30, 15, 3);
  444. bt_FM.cliked = false;
  445. bt_FM.selected = false;
  446. bt_FM.s="FM";
  447. bt_FM.affiche(GRIS_6, NOIR, 1);
  448.  
  449. bt_AIR.init(x0_box_BANDE+70, y0_box_BANDE+5, 30, 15, 3);
  450. bt_AIR.cliked = false;
  451. bt_AIR.selected = false;
  452. bt_AIR.s="AIR";
  453. bt_AIR.affiche(GRIS_6, NOIR, 1);
  454.  
  455. }
  456.  
  457.  
  458. void init_bouton_Mute()
  459. {
  460. int x0 = 5;
  461. int y0 = 120;
  462.  
  463. bt_mute.init(x0, y0, 30, 15, 3);
  464. bt_mute.selected = false;
  465. bt_mute.cliked = false;
  466. bt_mute.s="Mute";
  467. bt_mute.affiche(NOIR, ROUGE, 1);
  468. }
  469.  
  470.  
  471. void init_bouton_Sleep()
  472. {
  473. int x0 = 5;
  474. int y0 = 220;
  475.  
  476. bt_sleep.init(x0, y0, 40, 15, 3);
  477. bt_sleep.selected = false;
  478. bt_sleep.cliked = false;
  479. bt_sleep.s="Sleep";
  480. bt_sleep.affiche(NOIR, ROUGE, 1);
  481. }
  482.  
  483. void init_bouton_test()
  484. {
  485. int x0 = 160;
  486. int y0 = 120;
  487.  
  488. bt_test.init(x0, y0, 35, 15, 3);
  489. bt_test.selected = false;
  490. bt_test.cliked = false;
  491. bt_test.s="test";
  492. bt_test.affiche(GRIS_3, BLANC, 1);
  493. }
  494.  
  495.  
  496. void init_bt_affi_box_couleurs()
  497. {
  498. uint16_t c1 = NOIR;
  499. uint16_t c2 = VERT;
  500. bt_affi_box_couleurs.init(268, 223, 50, 15, 2);
  501. bt_affi_box_couleurs.cliked = false;
  502. bt_affi_box_couleurs.selected = false;
  503. bt_affi_box_couleurs.s = "couleur";
  504. bt_affi_box_couleurs.affiche(c1, c2, 1);
  505. }
  506.  
  507.  
  508.  
  509. void init_bouton_EE_RAZ()
  510. {
  511. TFT.setFreeFont(FF0);
  512. bt_EE_RAZ.init(x0_box_EEPROM+4, y0_box_EEPROM+20, 40, 15, 3);
  513.  
  514. bt_EE_RAZ.cliked = false;
  515. bt_EE_RAZ.selected = false;
  516.  
  517. bt_EE_RAZ.s="Raz";
  518. bt_EE_RAZ.affiche(GRIS_6, NOIR, 1);
  519. }
  520.  
  521.  
  522. void init_bouton_EE_write()
  523. {
  524. TFT.setFreeFont(FF0);
  525. bt_EE_write.init(x0_box_EEPROM+4, y0_box_EEPROM+40, 40, 15, 3);
  526.  
  527. bt_EE_write.cliked = false;
  528. bt_EE_write.selected = false;
  529.  
  530. bt_EE_write.s="Write";
  531. bt_EE_write.affiche(GRIS_6, NOIR, 1);
  532. }
  533.  
  534.  
  535. void init_bouton_EE_read()
  536. {
  537. TFT.setFreeFont(FF0);
  538. bt_EE_read.init(x0_box_EEPROM+4, y0_box_EEPROM+60, 40, 15, 3);
  539.  
  540. bt_EE_read.cliked = false;
  541. bt_EE_read.selected = false;
  542.  
  543. bt_EE_read.s="Read";
  544. bt_EE_read.affiche(GRIS_6, NOIR, 1);
  545. }
  546.  
  547.  
  548. void init_boutons_MODE()
  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, 17);
  556.  
  557. TFT.drawFastVLine(45, 15, 72, couleur_traits);
  558.  
  559. bt_mode_FRQ.init(5, 35, 35, 20, 3);
  560. bt_mode_FRQ.selected = true;
  561. bt_mode_FRQ.s="FRQ";
  562. bt_mode_FRQ.affiche(c1, c2, 1);
  563.  
  564. bt_mode_MEM.init(5, 60, 35, 20, 3);
  565. bt_mode_MEM.selected = false;
  566. bt_mode_MEM.s="MEM";
  567. bt_mode_MEM.affiche(c1, c2, 1);
  568.  
  569. affiche_index_frq();
  570. }
  571.  
  572.  
  573. void init_1_bouton_preset(uint16_t xi, uint16_t yi, String si, TOUCH_BOUTON_PRESET *bouton_i)
  574. {
  575. uint16_t c1 = NOIR;
  576. uint16_t c2 = BLANC;
  577.  
  578. if (mode_affi == COUL) {c1 = bouton_i->couleur;}
  579.  
  580. bouton_i->init(xi, yi, 15, 15, 3);
  581. bouton_i->cliked = false;
  582. bouton_i->selected = false;
  583. bouton_i->s = si;
  584. bouton_i->affiche(c1, c2, 1);
  585. }
  586.  
  587.  
  588. void init_boutons_presets()
  589. {
  590. uint16_t x = x0_box_PRESET +5;
  591. uint16_t y = y0_box_PRESET +5;
  592.  
  593. init_1_bouton_preset(x, y, "1", &bt_station1); x+=20;
  594. init_1_bouton_preset(x, y, "2", &bt_station2); x+=20;
  595. init_1_bouton_preset(x, y, "3", &bt_station3); x+=20;
  596. init_1_bouton_preset(x, y, "4", &bt_station4); x+=20;
  597. init_1_bouton_preset(x, y, "5", &bt_station5); x+=20;
  598. init_1_bouton_preset(x, y, "6", &bt_station6); x+=20;
  599. init_1_bouton_preset(x, y, "7", &bt_station7); x+=20;
  600. init_1_bouton_preset(x, y, "8", &bt_station8);
  601. }
  602.  
  603.  
  604. void affiche_1_bt_RGB(TOUCH_BOUTON *bouton_i, uint16_t x, uint16_t y, uint8_t dx, uint16_t couleur, String s_i)
  605. {
  606. uint16_t c1 = couleur;
  607. uint16_t c2 = JAUNE;
  608.  
  609. bouton_i->init(x, y, dx, 14, 3);
  610. bouton_i->cliked = false;
  611. bouton_i->selected = false;
  612. bouton_i->s = s_i;
  613. bouton_i->affiche(c1, c2, 1);
  614.  
  615. }
  616.  
  617.  
  618. void affiche_box_choix_couleur()
  619. {
  620. uint16_t x0 = x0_choix_couleur;
  621. uint16_t y0 = y0_choix_couleur;
  622. uint16_t x, y;
  623.  
  624. uint16_t c1 = GRIS_5;
  625. uint16_t c2 = JAUNE;
  626. TFT.setFreeFont(FF0);
  627. TFT.setTextColor(BLANC), NOIR;
  628.  
  629. TFT.drawRect(x0-1, y0-1, 142, 72, NOIR); // contour, visible sur fonds très clairs...
  630. TFT.fillRect(x0, y0, 140, 70, GRIS_2);
  631.  
  632. x = x0+15;
  633. y = y0+2;
  634.  
  635. TFT.drawString("R", x-10, y+5);
  636.  
  637. affiche_1_bt_RGB(&bt_R_moins, x, y, 18, GRIS_5, "-");
  638. x+=20;
  639. affiche_1_bt_RGB(&bt_R_plus, x, y, 18, GRIS_5, "+");
  640. x=x0+15; y+=18;
  641. TFT.drawString("G", x-10, y+5);
  642. affiche_1_bt_RGB(&bt_G_moins, x, y, 18, GRIS_5, "-");
  643. x+=20;
  644. affiche_1_bt_RGB(&bt_G_plus, x, y, 18, GRIS_5, "+");
  645. x=x0+15; y+=18;
  646. TFT.drawString("B", x-10, y+5);
  647. affiche_1_bt_RGB(&bt_B_moins, x, y, 18, GRIS_5, "-");
  648. x+=20;
  649. affiche_1_bt_RGB(&bt_B_plus, x, y, 18, GRIS_5, "+");
  650.  
  651. x=x0+122; y=y0;
  652. affiche_1_bt_RGB(&bt_close1, x, y, 18, GRIS_5, "x");
  653.  
  654. x=x0+5; y=y0+55;
  655. affiche_1_bt_RGB(&bt_coul_to_EEPROM, x, y, 60, ROUGE, "W EEPROM");
  656.  
  657. x=x0+100; y=y0+55;
  658. affiche_1_bt_RGB(&bt_RST_affi, x, y, 18, GRIS_5, "ok");
  659.  
  660. TFT.fillRoundRect(x0+80, y0+10, 40, 40, 5, couleur_fond_ecran);
  661.  
  662. RGB565_to_888(couleur_fond_ecran, &cR, &cG, &cB);
  663. affi_valeurs_RGB();
  664. }
  665.  
  666.  
  667.  
  668. void init_sprites()
  669. {
  670. sprite_frq.createSprite(220, 55);
  671. sprite_frq.loadFont(digitfont1);
  672. sprite_frq.setTextColor(JAUNE_2, NOIR);
  673. sprite_frq.setTextDatum(MR_DATUM); // alignement du texte
  674. }
  675.  
  676.  
  677. void Tuner_Reset(void)
  678. {
  679. Wire.beginTransmission(0x64);
  680. Wire.write(0x1e);
  681. Wire.write(0x5a);
  682. Wire.write(0x01);
  683. Wire.write(0x5a);
  684. Wire.write(0x5a);
  685. Wire.endTransmission();
  686. }
  687.  
  688.  
  689. bool Tuner_Table_Write(const unsigned char *tab)
  690. {
  691. if (tab[1] == 0xff)
  692. {
  693. delay(tab[2]);
  694. return 1;
  695. }
  696. else { return Tuner_WriteBuffer((unsigned char *)&tab[1], tab[0]); }
  697. }
  698.  
  699.  
  700. void Tuner_Init(const unsigned char *table)
  701. {
  702. uint16_t r;
  703. const unsigned char *p = table;
  704.  
  705. for (uint16_t i = 0; i < sizeof(tuner_init_tab9216); i += (pgm_read_byte(p + i) + 1))
  706. {
  707. if (1 != (r = Tuner_Table_Write(p + i))) break;
  708. }
  709. }
  710.  
  711.  
  712. void boutons_preset_set_frequences()
  713. {
  714. if(bande_active == FM)
  715. {
  716. bt_station1.frequence = 89400; bt_station1.nom = "Inter";
  717. bt_station2.frequence = 92900; bt_station2.nom = "Musique";
  718. bt_station3.frequence = 95600; bt_station3.nom = "RFM";
  719. bt_station4.frequence = 97800; bt_station4.nom = "Culture";
  720. bt_station5.frequence = 101100; bt_station5.nom = "Herault";
  721. bt_station6.frequence = 90600; bt_station6.nom = "RTL";
  722. bt_station7.frequence = 90100; bt_station7.nom = "FUN Radio";
  723. bt_station8.frequence = 107300; bt_station8.nom = "R Classique";
  724. }
  725.  
  726. if(bande_active == SW)
  727. {
  728. bt_station1.frequence = 9590; bt_station1.nom = "SW1";
  729. bt_station2.frequence = 11600; bt_station2.nom = "SW2";
  730. bt_station3.frequence = 13640; bt_station3.nom = "SW3";
  731. bt_station4.frequence = 17790; bt_station4.nom = "SW4";
  732. bt_station5.frequence = 8000; bt_station5.nom = "SW5";
  733. bt_station6.frequence = 12000; bt_station6.nom = "SW6";
  734. bt_station7.frequence = 18000; bt_station7.nom = "SW7";
  735. bt_station8.frequence = 24000; bt_station8.nom = "SW8";
  736. }
  737.  
  738. if(bande_active == AIR)
  739. {
  740. bt_station1.frequence = 131050; bt_station1.nom = "air1";
  741. bt_station2.frequence = 120925; bt_station2.nom = "air2";
  742. bt_station3.frequence = 124075; bt_station3.nom = "air3";
  743. bt_station4.frequence = 125000; bt_station4.nom = "air4";
  744. bt_station5.frequence = 124000; bt_station5.nom = "air5";
  745. bt_station6.frequence = 125000; bt_station6.nom = "air6";
  746. bt_station7.frequence = 126000; bt_station7.nom = "air7";
  747. bt_station8.frequence = 127000; bt_station8.nom = "air8";
  748. }
  749.  
  750. bt_station1.couleur = 10240; // rouge sombre
  751. bt_station2.couleur = 14528; // orange
  752. bt_station3.couleur = 320; // vert
  753. bt_station4.couleur = 14407; //violet
  754. bt_station5.couleur = 26787; // rose
  755. bt_station6.couleur = 260; //cyan
  756. bt_station7.couleur = 267; //bleu ciel
  757. bt_station8.couleur = 4; // bleu marine
  758. }
  759.  
  760.  
  761.  
  762. void Tune_Frequence(uint32_t F)
  763. {
  764. TFT.setFreeFont(FF0);
  765. TFT.setTextColor(BLEU, NOIR);
  766. String s1 = String(F);
  767. TFT.drawString(s1, 80, 4);
  768.  
  769. if (F == 1500)
  770. {
  771. //Tune_Frequence_AM(F);
  772. TFT.fillRect(130, 1, 100, 12, NOIR); // efface
  773. TFT.setTextColor(ROUGE, NOIR);
  774. TFT.drawString("MINIMUM ", 130, 4);
  775. }
  776.  
  777. if (bande_SW)
  778. {
  779. Tune_Frequence_AM(F);
  780. TFT.fillRect(130, 1, 100, 12, NOIR); // efface
  781. TFT.setTextColor(VERT, NOIR);
  782. TFT.drawString("SW ", 130, 4);
  783. }
  784.  
  785.  
  786. if (bande_interdite1)
  787. {
  788. //Tune_Frequence_AM(F);
  789. TFT.fillRect(130, 1, 100, 12, NOIR); // efface
  790. TFT.setTextColor(ROUGE, NOIR);
  791. TFT.drawString("NON DISPONIBLE", 130, 4);
  792. bt_SW.selected = false;
  793. bt_FM.selected = false;
  794. bt_AIR.selected = false;
  795. }
  796.  
  797. if (bande_FM)
  798. {
  799. Tune_Frequence_FM(F/10);
  800. TFT.fillRect(130, 1, 100, 12, NOIR); // efface
  801. TFT.setTextColor(VERT, NOIR);
  802. TFT.drawString("bande FM", 130, 4);
  803. }
  804.  
  805. if (bande_interdite2)
  806. {
  807. //Tune_Frequence_AM(F);
  808. TFT.fillRect(130, 1, 100, 12, NOIR); // efface
  809. TFT.setTextColor(ROUGE, NOIR);
  810. TFT.drawString("NON DISPONIBLE", 130, 4);
  811. bt_SW.selected = false;
  812. bt_FM.selected = false;
  813. bt_AIR.selected = false;
  814. }
  815.  
  816. if (bande_AIR)
  817. {
  818. Tune_Frequence_AM(F-110000); // nécessite un convertisseur de fréquence 110MHz en entrée antenne
  819. TFT.fillRect(130, 1, 100, 12, NOIR); // efface
  820. TFT.setTextColor(BLEU_CLAIR, NOIR);
  821. TFT.drawString("AIR BAND", 130, 4);
  822. }
  823.  
  824. if (F == 138000)
  825. {
  826. TFT.fillRect(130, 1, 40, 12, NOIR); // efface
  827. TFT.setTextColor(ROUGE, NOIR);
  828. TFT.drawString("F MAX ", 130, 4);
  829. }
  830. }
  831.  
  832.  
  833. void load_GRP_FREQ_EEPROM()
  834. {
  835. Serial.println("--- Frequences lues en EEPROM ---------------");
  836. Serial.println(" ");
  837. Serial.println("GROUPE SW");
  838. groupe_SW.load_bloc(); // EEPROM -> RAM
  839. groupe_SW.tri_bloc(); // en RAM
  840. groupe_SW.bloc_to_serial();
  841.  
  842. Serial.println("---------------------------------------------");
  843.  
  844. Serial.println("GROUPE FM");
  845. groupe_FM.load_bloc(); // EEPROM -> RAM
  846. groupe_FM.tri_bloc(); // en RAM
  847. groupe_FM.bloc_to_serial();
  848.  
  849. Serial.println("---------------------------------------------");
  850.  
  851. Serial.println("GROUPE AIR");
  852. groupe_AIR.load_bloc(); // EEPROM -> RAM
  853. groupe_AIR.tri_bloc(); // en RAM
  854. groupe_AIR.bloc_to_serial();
  855.  
  856. Serial.println("---------------------------------------------");
  857.  
  858. }
  859.  
  860.  
  861. uint16_t brightness(uint16_t couleur)
  862. {
  863. uint8_t r, g, b;
  864.  
  865. r = 0xFF & (couleur >> 16);
  866. g = 0xFF & (couleur >> 8);
  867. b = 0xFF & couleur;
  868.  
  869. return ( r + g + b );
  870. }
  871.  
  872.  
  873.  
  874.  
  875. void init_affichages()
  876. {
  877. TFT.fillScreen(couleur_fond_ecran); // couleur de fond d'écran
  878. if (brightness(couleur_fond_ecran) > 500) {couleur_traits = NOIR;} else {couleur_traits = BLANC;}
  879.  
  880.  
  881. TFT.setTextColor(JAUNE, NOIR);
  882.  
  883. TFT.drawRect(0, 0, 319, 240, couleur_traits); // cadre principal pourtour de l'écran
  884. init_sprites();
  885. while (!Serial && (millis() <= 1000));
  886. init_boutons_MODE();
  887. init_bouton_EE_RAZ();
  888. init_bouton_EE_write();
  889.  
  890. TFT.setFreeFont(FF0);
  891.  
  892. init_boutons_Plus_Moins();
  893. init_boutons_BANDE(); // (SW - FM - AIR)
  894. init_bouton_Mute();
  895. init_bouton_Sleep();
  896. init_bouton_test();
  897. init_bouton_EE_write();
  898. init_bouton_EE_read();
  899. numPad1.init(x0_numPad, y0_numPad, true);
  900.  
  901. affiche_box_entete();
  902. init_box_info();
  903. affiche_box_FRQ(GRIS_3);
  904. affiche_box_presets();
  905. affiche_box_BANDE();
  906. affiche_box_EEPROM();
  907.  
  908. init_boutons_presets();
  909.  
  910. uint16_t c1 = NOIR;
  911. uint16_t c2 = GRIS_2;
  912. bt_4.selected = true;
  913. bt_4.cliked = true;
  914. bt_4.affiche(c1, c2,1);
  915.  
  916. bt_mute.selected = false;
  917. bt_mute.cliked = false;
  918. bt_mute.affiche(NOIR, ROUGE, 1);
  919.  
  920. affiche_frequence(frequence);
  921.  
  922. if(mode_affi == VUM)
  923. {
  924. dessine_VuMetre();
  925. init_bt_affi_box_couleurs();
  926. }
  927.  
  928. if(mode_affi == COUL)
  929. {
  930. affiche_box_choix_couleur();
  931. }
  932. }
  933.  
  934.  
  935.  
  936.  
  937. void setup()
  938. {
  939. Serial.begin(115200);
  940.  
  941. #ifdef _SD_CARD
  942. init_SDcard(); // attention : incompatible avec le TOUCHPAD
  943. #endif
  944.  
  945. Wire.begin(GPIO_SDA, GPIO_SCL, 100000);
  946.  
  947. Serial.println("display.init()");
  948.  
  949. #ifndef _SD_CARD
  950. // Start the SPI for the touch screen and init the TS library
  951. // attention : incompatible avec SD_card
  952. mySpi.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS);
  953. ts.begin(mySpi);
  954. ts.setRotation(3);
  955. #endif
  956.  
  957.  
  958. TFT.init();
  959. TFT.setRotation(3); // 0..3 à voir, suivant disposition de l'afficheur et sa disposition
  960. TFT.fillScreen(NOIR);
  961.  
  962.  
  963. TFT.setTextColor(BLANC, NOIR);
  964. TFT.setFreeFont(FF1);
  965. uint16_t y=0;
  966. Serial.println("Radio TEF6686");
  967. TFT.drawString("Radio TEF6686", 0, y); y+=20;
  968. String s1="version " + version;
  969. TFT.drawString(s1, 0, y); y+=20;
  970. TFT.drawString("Silicium628", 0, y); y+=40;
  971. TFT.setFreeFont(FF0);
  972. TFT.drawString("SW (AM) 1500kHz -- 28MHz", 0, y); y+=20;
  973. TFT.drawString("bande FM (WFM) 88MHz -- 108MHz", 0, y); y+=20;
  974. TFT.drawString("Civil Air band(AM) 118MHz -- 137MHz", 0, y); y+=20;
  975. delay(1000);
  976.  
  977.  
  978. // adresses physiques des blocs en EEPROM:
  979. groupe_SW.adr_0 = 100; // je réserve les 100 premiers octets (0..99) pour des paramètres divers
  980. groupe_FM.adr_0 = groupe_SW.adr_0 + 400; // donc =500 (chaque fréquence occupe 4 octets (uint_32t))
  981. groupe_AIR.adr_0 = groupe_FM.adr_0 + 400; // donc =900
  982.  
  983. boutons_preset_set_frequences();
  984.  
  985. EEPROM.begin(EEPROM_SIZE);
  986. couleur_fond_ecran = EEPROM.readShort(0); // 2 octets = 16 bits
  987. frequence = EEPROM.readUInt(EEPROM_adrs_freq); // 4 octets = 32 bits
  988.  
  989.  
  990.  
  991. Serial.print("mode_s LU en EEPROM: "); Serial.println(mode_s);
  992.  
  993. init_affichages();
  994.  
  995. Serial.print("mode_s ici2: "); Serial.println(mode_s);
  996.  
  997. Serial.println("---------------------------------------------");
  998.  
  999. saut_freq = 100;
  1000. Tuner_Init(tuner_init_tab9216);
  1001.  
  1002. Serial.println(" ");
  1003. /*
  1004. The TEF668X consists of four modules:
  1005. -module 32 : FM = FM radio reception
  1006. -module 33 : AM = LW, MW and SW radio reception
  1007. -module 48 : AUDIO = Audio processing
  1008. -module 64 : APPL = System and application control
  1009. */
  1010.  
  1011. load_GRP_FREQ_EEPROM();
  1012.  
  1013. Set_no_AM_gain_reduction();
  1014.  
  1015. mode_s = EEPROM.readByte(EEPROM_adrs_mode); // 1 octet
  1016. if(mode_s == _FRQ) {bt_mode_FRQ.selected = true; bt_mode_MEM.selected = false;}
  1017. if(mode_s == _MEM) {bt_mode_FRQ.selected = false; bt_mode_MEM.selected = true;}
  1018. uint16_t c1 = GRIS_6;
  1019. uint16_t c2 = VERT;
  1020. uint16_t c3 = JAUNE;
  1021. bt_mode_FRQ.affiche(c1, c2, 1);
  1022. bt_mode_MEM.affiche(c1, c3, 1);
  1023.  
  1024. uint32_t Frq = EEPROM.readUInt(EEPROM_adrs_freq); // 4 octets = 32 bits
  1025. if (Frq != 0)
  1026. {
  1027. deselect_boutons_presets();
  1028. frequence = Frq;
  1029. }
  1030. else
  1031. {
  1032. frequence = bt_station4.frequence;
  1033. clic_logiciel_bouton(&bt_station4);
  1034. }
  1035. affiche_frequence(frequence);
  1036. Tune_Frequence(frequence);
  1037.  
  1038. Set_Volume(+60);
  1039.  
  1040. Serial.print("mode_s ici3: "); Serial.println(mode_s);
  1041. Serial.print("------------- FIN DU SETUP -----------------");
  1042.  
  1043. delay(100);
  1044.  
  1045.  
  1046. // FIN DU SETUP
  1047. }
  1048.  
  1049.  
  1050. void printTouchToDisplay(TS_Point p)
  1051. {
  1052. // Clear screen first
  1053. //TFT.fillScreen(TFT_BLACK);
  1054. //TFT.setTextColor(TFT_WHITE, TFT_BLACK);
  1055.  
  1056. int x = 320 / 2; // center of display
  1057. int y = 100;
  1058. int fontSize = 2;
  1059.  
  1060. //String temp = "P= " + String(p.z);
  1061. //TFT.drawCentreString(temp, x, y, fontSize);
  1062.  
  1063. x_touch = -30 + p.x /11;
  1064. y_touch = -30 + p.y /14;
  1065.  
  1066. // TFT.drawRect(x_touch, y_touch, 2, 2, JAUNE;
  1067. }
  1068.  
  1069. float ltx = 0; // Saved x coord of bottom of aiguille
  1070. uint16_t osx = x0_vu_metre;
  1071. uint16_t osy = y0_vu_metre;
  1072.  
  1073.  
  1074. // -------------------------------------------------------------------------
  1075. void dessine_VuMetre()
  1076. {
  1077. uint16_t x0 = x0_vu_metre;
  1078. uint16_t y0 = y0_vu_metre;
  1079.  
  1080. uint16_t dx=140;
  1081. uint16_t dy=70;
  1082.  
  1083. uint8_t AA = 65; // 65
  1084. uint8_t BB = x0 +dx/2;// 120
  1085. uint8_t CC = y0 + dy+20; // 140
  1086.  
  1087. TFT.setFreeFont(FF0);
  1088. // cadre rectangulaire
  1089. TFT.fillRect(x0, y0, dx, dy, GRIS_3);
  1090. TFT.fillRect(x0+3, y0+3, dx-6, dy-6, BLANC);
  1091.  
  1092. TFT.setTextColor(NOIR);
  1093.  
  1094. // graduation chaque 5 deg entre -50 et +50 deg
  1095. for (int i = -50; i < 51; i += 10)
  1096. {
  1097. int tl = 5; // tiret plus long
  1098. // Coordonnées du tiret à dessiner
  1099. float sx = cos((i - 90) * deg_to_rad);
  1100. float sy = sin((i - 90) * deg_to_rad);
  1101. uint16_t tx0 = sx * (AA + tl) + BB;
  1102. uint16_t ty0 = sy * (AA + tl) + CC;
  1103. uint16_t tx1 = sx * AA + BB;
  1104. uint16_t ty1 = sy * AA + CC;
  1105.  
  1106. // Coordonnées of next tick for zone fill
  1107. float sx2 = cos((i + 5 - 90) * deg_to_rad);
  1108. float sy2 = sin((i + 5 - 90) * deg_to_rad);
  1109. int tx2 = sx2 * (AA + tl) + BB;
  1110. int ty2 = sy2 * (AA + tl) + CC;
  1111. int tx3 = sx2 * AA + BB;
  1112. int ty3 = sy2 * AA + CC;
  1113.  
  1114. // zone verte
  1115. if (i >= 0 && i < 25)
  1116. {
  1117. TFT.fillTriangle(tx0, ty0, tx1, ty1, tx2, ty2, VERT);
  1118. TFT.fillTriangle(tx1, ty1, tx2, ty2, tx3, ty3, VERT);
  1119. }
  1120.  
  1121. // zone orange
  1122. if (i >= 25 && i < 50)
  1123. {
  1124. TFT.fillTriangle(tx0, ty0, tx1, ty1, tx2, ty2, ORANGE);
  1125. TFT.fillTriangle(tx1, ty1, tx2, ty2, tx3, ty3, ORANGE);
  1126. }
  1127.  
  1128. if (i % 25 != 0) tl = 8; // Short scale tick length
  1129.  
  1130. // Recalcule coords in case tick lenght changed
  1131. tx0 = sx * (AA + tl) + BB;
  1132. ty0 = sy * (AA + tl) + CC;
  1133. tx1 = sx * AA + BB;
  1134. ty1 = sy * AA + CC;
  1135.  
  1136. // Draw tick
  1137. TFT.drawLine(tx0, ty0, tx1, ty1, NOIR);
  1138.  
  1139. // Check if labels should be drawn, with position tweaks
  1140. if (i % 20 == 0)
  1141. {
  1142. // Calculate label positions
  1143. tx0 = sx * (AA + tl + 10) + BB;
  1144. ty0 = sy * (AA + tl + 10) + CC;
  1145. switch (i / 20)
  1146. {
  1147. case -2: TFT.drawCentreString("0", tx0, ty0 - 6, 1); break;
  1148. case -1: TFT.drawCentreString("25", tx0, ty0 - 4, 1); break;
  1149. case 0: TFT.drawCentreString("50", tx0, ty0 - 6, 1); break;
  1150. case 1: TFT.drawCentreString("75", tx0, ty0 - 4, 1); break;
  1151. case 2: TFT.drawCentreString("100", tx0, ty0 - 6, 1); break;
  1152. }
  1153. }
  1154. // draw the arc of the scale
  1155. sx = cos((i + 5 - 90) * deg_to_rad);
  1156. sy = sin((i + 5 - 90) * deg_to_rad);
  1157. tx0 = sx * AA + BB;
  1158. ty0 = sy * AA + CC;
  1159. // Draw scale arc, don't draw the last part
  1160. if (i < 50) {TFT.drawLine(tx0, ty0, tx1, ty1, NOIR);}
  1161. }
  1162. //TFT.drawRect(x0, y0+dy-20, dx, 20, NOIR);
  1163. }
  1164.  
  1165.  
  1166.  
  1167.  
  1168. void plotAiguille(float value)
  1169. {
  1170. uint16_t x0 = x0_vu_metre;
  1171. uint16_t y0 = y0_vu_metre;
  1172. uint16_t dx=140;
  1173. uint16_t dy=50;
  1174.  
  1175. uint8_t AA = dx/2; // 100
  1176. uint8_t BB = x0 +dx/2;// 120
  1177. uint8_t CC = y0 + dy+25; // 140
  1178.  
  1179. TFT.setTextColor(TFT_BLACK, BLANC);
  1180. char buf[8]; dtostrf(value, 4, 0, buf);
  1181.  
  1182. if (value < -10) value = -10; // Limit value to emulate aiguille end stops
  1183. if (value > 110) value = 110;
  1184.  
  1185. float sdeg = map(value, -10, 110, -150, -30); // Map value to angle
  1186. // Calcul aiguille coords
  1187. float sx = cos(sdeg * deg_to_rad);
  1188. float sy = sin(sdeg * deg_to_rad);
  1189.  
  1190. // Calcul x delta of aiguille start (does not start at pivot point)
  1191. float tx = tan((sdeg + 90) * deg_to_rad);
  1192.  
  1193. // Erase old aiguille image
  1194. TFT.drawLine(BB + 20 * ltx - 1, CC - 20, osx - 1, osy, BLANC);
  1195. TFT.drawLine(BB + 20 * ltx, CC - 20, osx, osy, BLANC);
  1196. TFT.drawLine(BB + 20 * ltx + 1, CC - 20, osx + 1, osy, BLANC);
  1197.  
  1198.  
  1199. // Store new aiguille end coords for next erase
  1200. ltx = tx;
  1201. osx = sx * 50 + BB;
  1202. osy = sy * 50 + CC;
  1203.  
  1204. // Draw aiguille in the new postion
  1205. // draws 3 lines to thicken aiguille
  1206. TFT.drawLine(BB + 20 * ltx - 1, CC - 20, osx - 1, osy, ROUGE);
  1207. TFT.drawLine(BB + 20 * ltx, CC - 20, osx, osy, VIOLET);
  1208. TFT.drawLine(BB + 20 * ltx + 1, CC - 20, osx + 1, osy, ROUGE);
  1209.  
  1210. TFT.fillRect(x0, y0+dy+5, dx, 15, GRIS_2);
  1211. }
  1212.  
  1213.  
  1214.  
  1215. void init_box_info()
  1216. {
  1217. TFT.drawRect(x0_box_info, y0_box_info, 180, 16, NOIR);
  1218. TFT.setFreeFont(FF0);
  1219. TFT.setTextColor(JAUNE, couleur_fond_ecran);
  1220. TFT.drawString("RDS", x0_box_info -20, y0_box_info + 4);
  1221. }
  1222.  
  1223.  
  1224. void affiche_unit(String s)
  1225. {
  1226. TFT.setTextColor(JAUNE, NOIR);
  1227. TFT.setFreeFont(FM9); //FM9 FMB9 FSS9... voir le fichier Free_Fonts.h
  1228. TFT.drawString(s, FRQ_x0 + 225, FRQ_y0 + 35);
  1229. }
  1230.  
  1231.  
  1232. void efface_numero_frq()
  1233. {
  1234. TFT.fillRect(FRQ_x0 + 225, FRQ_y0 + 20, 40, 12, couleur_fond_ecran);
  1235. }
  1236.  
  1237.  
  1238. void affiche_numero_frq(String s1, String s2)
  1239. {
  1240. //TFT.fillRect(FRQ_x0 + 225, FRQ_y0 + 5, 10, 10, BLEU);
  1241. TFT.setTextColor(BLANC, couleur_fond_ecran);
  1242. TFT.setFreeFont(FF0);
  1243. TFT.drawString(s1 + "/" + s2 + " ", FRQ_x0 + 225, FRQ_y0 + 20);
  1244. affiche_box_FRQ(GRIS_3); // pour retracer le côté droit du rectangle
  1245. }
  1246.  
  1247.  
  1248. void affiche_band(String s)
  1249. {
  1250. //TFT.fillRect(FRQ_x0 + 225, FRQ_y0 + 5, 10, 10, BLEU);
  1251. TFT.setTextColor(BLANC, NOIR);
  1252. TFT.setFreeFont(FM9);
  1253. String blancs;
  1254. if (s == "AIR") {blancs = " ";} else {blancs = " ";}
  1255.  
  1256. TFT.drawString(s + blancs, FRQ_x0 + 225, FRQ_y0);
  1257. affiche_box_FRQ(GRIS_3); // pour retracer le côté droit du rectangle
  1258. }
  1259.  
  1260.  
  1261. void affiche_box_entete()
  1262. {
  1263. TFT.fillRect(0, 0, 320, 14, NOIR);
  1264.  
  1265. }
  1266.  
  1267.  
  1268. void affiche_box_FRQ(uint16_t couleur) // autour de la fréquence (en gros chiffres JAUNE
  1269. {
  1270. TFT.drawRect(0, FRQ_y0 -17, 319, 74, couleur);
  1271. }
  1272.  
  1273.  
  1274. void affiche_box_presets() // boutons 1 2 3 4 5 6 7 8
  1275. {
  1276. TFT.fillRect(x0_box_PRESET, y0_box_PRESET, 164, 24, NOIR);
  1277. TFT.setTextColor(GRIS_3, NOIR);
  1278. //TFT.drawString("presets", 5, 90);
  1279. }
  1280.  
  1281. void affiche_box_BANDE() // les 3 boutons SW, FM, AIR
  1282. {
  1283. TFT.drawRect(x0_box_BANDE, y0_box_BANDE, 105, 25, couleur_traits);
  1284. TFT.setFreeFont(FF0);
  1285. }
  1286.  
  1287.  
  1288. void affiche_box_EEPROM() // RAZ, WRITE, READ ...
  1289. {
  1290. TFT.drawRect(x0_box_EEPROM, y0_box_EEPROM + 10, 50, 70, couleur_traits);
  1291. TFT.setFreeFont(FF0);
  1292. TFT.setTextColor(GRIS_3, NOIR);
  1293. TFT.drawString("EEPROM", x0_box_EEPROM+6, y0_box_EEPROM+6);
  1294. }
  1295.  
  1296.  
  1297.  
  1298.  
  1299. void affiche_frequence(uint32_t frq) // en kHz, sans décimales
  1300. {
  1301. uint16_t c1 = NOIR;
  1302. uint16_t c2 = VERT;
  1303. uint16_t couleur_chiffres;
  1304.  
  1305. if(mode_s == _FRQ) {couleur_chiffres = VERT_chiffres;}
  1306. if(mode_s == _MEM) {couleur_chiffres = JAUNE_chiffres;}
  1307.  
  1308. if(bande_SW) // SW - 28 MHz = limite haute du module
  1309. {
  1310. affiche_band("SW");
  1311. bande_active = SW;
  1312. boutons_preset_set_frequences();
  1313. bt_SW.selected = true;
  1314. bt_FM.selected = false; // les boutons sont exclusifs
  1315. bt_AIR.selected = false;
  1316. bt_SW.affiche(c1, c2, 1); bt_FM.affiche(c1, c2, 1); bt_AIR.affiche(c1, c2, 1);
  1317.  
  1318. String s1, sM, sK;
  1319. uint8_t L;
  1320.  
  1321. s1 = String(frq);
  1322. s1 = "000000" + s1;
  1323. L= s1.length();
  1324.  
  1325. sK = s1.substring(L-3); // kHz
  1326. sM = s1.substring(L-6, L-3); // Mhz
  1327.  
  1328. sprite_frq.fillRect(0,0,220, 60, NOIR); // efface
  1329.  
  1330. sprite_frq.setTextColor(couleur_chiffres, NOIR);
  1331. sprite_frq.drawString(sM + "." + sK + " ", 220+10, 32);
  1332. // remarque: le fait d'ajouter " " à la fin évite aux chiffres de se balader horizontalement !
  1333. sprite_frq.pushSprite(FRQ_x0, FRQ_y0);
  1334. affiche_unit("MHz");
  1335. Tune_Frequence(frq);
  1336. }
  1337.  
  1338. if(bande_FM) // bande FM, on efface les deux '0' de droite
  1339. {
  1340. affiche_band("FM");
  1341. bande_active = FM;
  1342. boutons_preset_set_frequences();
  1343. bt_FM.selected = true;
  1344. bt_SW.selected = false; // les boutons sont exclusifs
  1345. bt_AIR.selected = false;
  1346. bt_SW.affiche(c1, c2, 1); bt_FM.affiche(c1, c2, 1); bt_AIR.affiche(c1, c2, 1);
  1347.  
  1348. String s1, sM, sK;
  1349. uint8_t L;
  1350.  
  1351. s1 = String(frq);
  1352. s1 = "000000" + s1;
  1353. L= s1.length();
  1354.  
  1355. sK = s1.substring(L-3, L-2); // kHz
  1356.  
  1357. if (frq < 100000) {sM = s1.substring(L-5, L-3); }// on ne retient que deux chiffres à gauche du point
  1358. else { sM = s1.substring(L-6, L-3); } // on garde 3 chiffres à gauche du point décimal
  1359.  
  1360. sprite_frq.fillRect(0,0,220, 60, NOIR); // efface
  1361. sprite_frq.setTextColor(couleur_chiffres, NOIR);
  1362. sprite_frq.drawString(sM + "." + sK + " ", 220-50, 32);
  1363. // remarque: le fait d'ajouter " " à la fin évite aux chiffres de se balader horizontalement !
  1364. sprite_frq.pushSprite(FRQ_x0, FRQ_y0);
  1365. affiche_unit("MHz");
  1366.  
  1367. Tune_Frequence(frq);
  1368. bt_mute.selected = false;
  1369. bt_mute.cliked = false;
  1370. bt_mute.affiche(NOIR, ROUGE, 1);
  1371. }
  1372.  
  1373. if(bande_AIR) // bande AIR - 138000-110000 = 28MHz (limite haute de réception AM du module)
  1374. {
  1375. affiche_band("AIR");
  1376. bande_active = AIR;
  1377. boutons_preset_set_frequences();
  1378. bt_AIR.selected = true;
  1379. bt_SW.selected = false; // les boutons sont exclusifs
  1380. bt_FM.selected = false;
  1381. bt_SW.affiche(c1, c2, 1); bt_FM.affiche(c1, c2, 1); bt_AIR.affiche(c1, c2, 1);
  1382.  
  1383. String s1, sM, sK;
  1384. uint8_t L;
  1385.  
  1386. s1 = String(frq);
  1387. s1 = "000000" + s1;
  1388. L= s1.length();
  1389.  
  1390. sK = s1.substring(L-3); // kHz
  1391. sM = s1.substring(L-6, L-3); // Mhz
  1392.  
  1393. sprite_frq.fillRect(0,0,220, 60, NOIR); // efface
  1394. sprite_frq.setTextColor(couleur_chiffres, NOIR);
  1395. sprite_frq.drawString(sM + "." + sK + " ", 220+10, 32);
  1396. // remarque: le fait d'ajouter " " à la fin évite aux chiffres de se balader horizontalement !
  1397. sprite_frq.pushSprite(FRQ_x0, FRQ_y0);
  1398. affiche_unit("MHz");
  1399. Tune_Frequence(frq);
  1400. }
  1401.  
  1402. if(bande_interdite1 || bande_interdite2) // bandes interdites par le module TEF6686
  1403. {
  1404. affiche_band("---");
  1405.  
  1406. String s1, sM, sK;
  1407. uint8_t L;
  1408.  
  1409. s1 = String(frq);
  1410. s1 = "000000" + s1;
  1411. L= s1.length();
  1412.  
  1413. sK = s1.substring(L-3); // kHz
  1414. sM = s1.substring(L-6, L-3); // Mhz
  1415.  
  1416. sprite_frq.fillRect(0,0,220, 60, NOIR); // efface
  1417. sprite_frq.setTextColor(couleur_chiffres, NOIR);
  1418. sprite_frq.drawString(sM + "." + sK + " ", 220+10, 32);
  1419. // remarque: le fait d'ajouter " " à la fin évite aux chiffres de se balader horizontalement !
  1420. sprite_frq.pushSprite(FRQ_x0, FRQ_y0);
  1421. affiche_unit("MHz");
  1422. //Tune_Frequence(frq);
  1423.  
  1424. }
  1425.  
  1426. if(frq==138000) { affiche_band("max"); }
  1427. if(frq>138000) { affiche_band("---"); }
  1428. }
  1429.  
  1430.  
  1431. void clic_logiciel_bouton(TOUCH_BOUTON *bouton_i)
  1432. {
  1433. uint16_t c1 = NOIR;
  1434. uint16_t c2 = BLEU;
  1435.  
  1436. bouton_i->cliked = true;
  1437. bouton_i->selected = true;
  1438. bouton_i->affiche(c1, c2, 1);
  1439. }
  1440.  
  1441.  
  1442.  
  1443. void test_clic_boutons(TOUCH_BOUTON *bouton_i)
  1444. {
  1445. uint16_t c1 = NOIR;
  1446. uint16_t c2 = GRIS_2;
  1447.  
  1448. if ((x_touch > bouton_i->x0) && (x_touch < bouton_i->x0 + bouton_i->dx)
  1449. && ( y_touch > bouton_i->y0-5) && (y_touch < bouton_i->y0 + bouton_i->dy +5) )
  1450. {
  1451. bouton_i->cliked = true;
  1452. bouton_i->selected = true;
  1453. bouton_i->affiche(c1, c2, 1);
  1454. }
  1455. }
  1456.  
  1457.  
  1458.  
  1459. void test_clic_6_boutons_frq() //rectangles situés au dessus des gros chiffres de la fréquence
  1460. {
  1461. uint16_t c1 = NOIR;
  1462. uint16_t c2 = VERT;
  1463.  
  1464. if (( y_touch > (bt_1.y0-10)) && (y_touch < (bt_1.y0 + bt_1.dy+10)) ) // zone des 6 boutons au dessus de la fréquence
  1465. {
  1466. bt_1.cliked = false; bt_1.selected = false; test_clic_boutons(&bt_1 ); bt_1.affiche(c1, c2,1);
  1467. bt_2.cliked = false; bt_2.selected = false; test_clic_boutons(&bt_2 ); bt_2.affiche(c1, c2,1);
  1468. bt_3.cliked = false; bt_3.selected = false; test_clic_boutons(&bt_3 ); bt_3.affiche(c1, c2,1);
  1469. bt_4.cliked = false; bt_4.selected = false; test_clic_boutons(&bt_4 ); bt_4.affiche(c1, c2,1);
  1470. bt_5.cliked = false; bt_5.selected = false; test_clic_boutons(&bt_5 ); bt_5.affiche(c1, c2,1);
  1471. bt_6.cliked = false; bt_6.selected = false; test_clic_boutons(&bt_6 ); bt_6.affiche(c1, c2,1);
  1472.  
  1473. if (bt_6.cliked) {saut_freq = 1;}
  1474. if (bt_5.cliked) {saut_freq = 10;}
  1475. if (bt_4.cliked) {saut_freq = 100;}
  1476. if (bt_3.cliked) {saut_freq = 1000;}
  1477. if (bt_2.cliked) {saut_freq = 10000;}
  1478. if (bt_1.cliked) {saut_freq = 100000;}
  1479. }
  1480. }
  1481.  
  1482.  
  1483. void traite_touches_pad(uint8_t num_touche)
  1484. {
  1485.  
  1486. if(num_touche == 253) {return;}
  1487.  
  1488. uint16_t c1 = GRIS_6;
  1489. uint16_t c2 = JAUNE;
  1490. uint16_t c3 = VERT;
  1491.  
  1492. int p1;
  1493.  
  1494. if (num_touche == 254) // bouton "."
  1495. {
  1496. frequence_txt += ".";
  1497. TFT.drawString(frequence_txt + " ", 250, 0);
  1498. }
  1499.  
  1500. if (num_touche < 10)
  1501. {
  1502. TFT.fillRect(250, 1, 60, 12, NOIR); // efface
  1503. frequence_txt += String(num_touche);
  1504. TFT.drawString(frequence_txt + " ", 250, 0);
  1505. delay(300);
  1506. }
  1507.  
  1508. x_touch =0;
  1509. y_touch =0;
  1510.  
  1511. if (num_touche == 255) // bouton "ok"
  1512. {
  1513. mode_s = _FRQ;
  1514. bt_mode_MEM.selected = false;
  1515. bt_mode_FRQ.selected = true;
  1516.  
  1517. bt_mode_MEM.affiche(c1, c2, 1);
  1518. bt_mode_FRQ.affiche(c1, c3, 1);
  1519.  
  1520.  
  1521. double F;
  1522. F = frequence_txt.toDouble();
  1523. p1 = frequence_txt.indexOf(".");
  1524. if (p1 != -1) {F *=1000;} // si présence du point décimal
  1525.  
  1526. frequence = F;
  1527. affiche_frequence(frequence); // 'Tune_Frequence(frq)' est appelée dans cette fonction 'affiche_frequence()'
  1528.  
  1529. n_appui = 0;
  1530. frequence_txt = "";
  1531. TFT.fillRect(250, 1, 60, 12, NOIR); // efface
  1532.  
  1533. n_appui = 0;
  1534.  
  1535. }
  1536. num_touche = 0;
  1537. }
  1538.  
  1539.  
  1540.  
  1541. uint32_t inc_Frq_in_groupe(GROUPE_FREQUENCES *groupe_Freq, int8_t di) // di = +/-1
  1542. {
  1543. if ((di<-1)||(di>1)) {return 0;}
  1544.  
  1545. uint16_t n_max = groupe_Freq->nb_freq;
  1546. uint16_t n = groupe_Freq->num_F_actuelle;
  1547.  
  1548. if (di == 1)
  1549. {
  1550. if (n<n_max-1) { n++; }
  1551. else if (n == (n_max-1)) {n=0;}
  1552. }
  1553.  
  1554. if (di == -1)
  1555. {
  1556. if (n>=1) { n--; }
  1557. else if (n==0) {n = n_max-1;}
  1558. }
  1559.  
  1560. groupe_Freq->num_F_actuelle = n;
  1561. uint16_t adr = groupe_Freq->adr_1ere_frq + n;
  1562.  
  1563. uint8_t nb_F = groupe_Freq->nb_freq;
  1564. uint8_t num_1ere_F = groupe_Freq->adr_1ere_frq;
  1565. affiche_numero_frq(String(1 + adr - num_1ere_F), String(nb_F));
  1566.  
  1567. uint32_t valeur_lue = groupe_Freq->G_freq[adr];
  1568. return valeur_lue;
  1569. }
  1570.  
  1571.  
  1572.  
  1573. void test_clic_boutons_plus_moins()
  1574. {
  1575. uint16_t c1 = GRIS_6;
  1576. uint16_t c2 = GRIS_3;
  1577.  
  1578. boolean bouton_cliked = false;
  1579. //uint16_t n=0;
  1580. affiche_box_entete(); // efface
  1581.  
  1582. //---------------------------------------------------------------------------------
  1583. if(mode_s == _FRQ) // on va modifier directement la fréquence
  1584. {
  1585. test_clic_boutons(&bt_plus ); bt_plus.affiche(c1, c2, 1);
  1586. if (bt_plus.cliked)
  1587. {
  1588. frequence += saut_freq;
  1589. bouton_cliked = true;
  1590. }
  1591.  
  1592. delay(20);
  1593. if (bt_plus.cliked && ((frequence + saut_freq) <= 138000 ))
  1594. {
  1595. Tune_Frequence(frequence);
  1596. }
  1597.  
  1598. bt_plus.cliked = false;
  1599. bt_plus.selected = false;
  1600. bt_plus.affiche(c1, c2, 1); // fugitif
  1601.  
  1602. test_clic_boutons(&bt_moins ); bt_moins.affiche(c1, c2, 2);
  1603. delay(20);
  1604. if (bt_moins.cliked)
  1605. {
  1606. if (frequence > saut_freq) // évite de se retrouver avec une F négative !
  1607. {
  1608. bouton_cliked = true;
  1609. frequence -= saut_freq;
  1610. }
  1611. }
  1612. if(bt_moins.cliked && frequence > saut_freq) { Tune_Frequence(frequence); }
  1613. bt_moins.cliked = false;
  1614. bt_moins.selected = false;
  1615. bt_moins.affiche(c1, c2, 2); // fugitif
  1616.  
  1617. if(bouton_cliked == true)
  1618. {
  1619. bouton_cliked = false;
  1620. affiche_frequence(frequence);
  1621. }
  1622. }
  1623.  
  1624. //---------------------------------------------------------------------------------
  1625. if(mode_s == _MEM) // on va parcourir les fréquences de la liste
  1626. {
  1627. test_clic_boutons(&bt_plus ); bt_plus.affiche(c1, c2, 1);
  1628. if (bt_plus.cliked)
  1629. {
  1630. bouton_cliked = true;
  1631.  
  1632. if(bande_active == SW) { frequence = inc_Frq_in_groupe(&groupe_SW, 1); }
  1633. if(bande_active == FM) { frequence = inc_Frq_in_groupe(&groupe_FM, 1); }
  1634. if(bande_active == AIR) { frequence = inc_Frq_in_groupe(&groupe_AIR, 1); }
  1635.  
  1636. Tune_Frequence(frequence);
  1637. delay(100);
  1638. }
  1639.  
  1640. bt_plus.cliked = false;
  1641. bt_plus.selected = false;
  1642. bt_plus.affiche(c1, c2, 1); // fugitif
  1643.  
  1644. test_clic_boutons(&bt_moins ); bt_moins.affiche(c1, c2, 2);
  1645. delay(20);
  1646. if (bt_moins.cliked)
  1647. {
  1648. bouton_cliked = true;
  1649.  
  1650. if(bande_active == SW) { frequence = inc_Frq_in_groupe(&groupe_SW, -1); }
  1651. if(bande_active == FM) { frequence = inc_Frq_in_groupe(&groupe_FM, -1); }
  1652. if(bande_active == AIR) { frequence = inc_Frq_in_groupe(&groupe_AIR, -1); }
  1653.  
  1654. Tune_Frequence(frequence);
  1655. delay(100);
  1656. }
  1657. bt_moins.cliked = false;
  1658. bt_moins.selected = false;
  1659. bt_moins.affiche(c1, c2, 2); // fugitif
  1660.  
  1661. if(bouton_cliked == true)
  1662. {
  1663. bouton_cliked = false;
  1664. affiche_frequence(frequence);
  1665. }
  1666. }
  1667. }
  1668.  
  1669.  
  1670. void test_clic_bt_RST_affi() // bouton "ok" de la box saisie couleur de fond ecran
  1671. {
  1672. if(mode_affi != COUL) {return;}
  1673.  
  1674. uint16_t c1 = GRIS_6;
  1675. uint16_t c2 = JAUNE;
  1676.  
  1677. test_clic_boutons(&bt_RST_affi );
  1678. //bt_sleep.affiche(NOIR, ROUGE, 1);
  1679. //delay(100);
  1680. if (bt_RST_affi.cliked)
  1681. {
  1682. bt_RST_affi.cliked = false;
  1683. bt_RST_affi.selected = true;
  1684. bt_RST_affi.affiche(NOIR, VERT, 1);
  1685.  
  1686. init_affichages();
  1687. }
  1688. }
  1689.  
  1690.  
  1691.  
  1692. void test_clic_bt_affi_box_couleurs() // bouton au coin en bas à droite
  1693. {
  1694. uint16_t c1 = GRIS_6;
  1695. uint16_t c2 = JAUNE;
  1696.  
  1697. test_clic_boutons(&bt_affi_box_couleurs );
  1698. //bt_sleep.affiche(NOIR, ROUGE, 1);
  1699. //delay(100);
  1700. if (bt_affi_box_couleurs.cliked)
  1701. {
  1702. bt_affi_box_couleurs.cliked = false;
  1703. bt_affi_box_couleurs.selected = true;
  1704. bt_affi_box_couleurs.affiche(NOIR, VERT, 1);
  1705.  
  1706. mode_affi = COUL;
  1707. init_affichages();
  1708. }
  1709. }
  1710.  
  1711.  
  1712. void test_clic_bt_coul_to_EEPROM() // enregistre la couleur en EEPROM
  1713. {
  1714. if(mode_affi != COUL) {return;} // pour ne pas détecter le clic sur un bouton invisible !
  1715.  
  1716. uint16_t c1 = GRIS_6;
  1717. uint16_t c2 = JAUNE;
  1718.  
  1719. test_clic_boutons(&bt_coul_to_EEPROM );
  1720.  
  1721. if (bt_coul_to_EEPROM.cliked)
  1722. {
  1723. bt_coul_to_EEPROM.cliked = false;
  1724. bt_coul_to_EEPROM.selected = true;
  1725. bt_coul_to_EEPROM.affiche(NOIR, VERT, 1);
  1726.  
  1727. EEPROM.writeShort(EEPROM_adrs_couleur, couleur_fond_ecran); // write 1 mot de 16 bits soit 2 octets
  1728. EEPROM.commit();
  1729.  
  1730. mode_affi = VUM;
  1731. init_affichages();
  1732. delay(200);
  1733. init_affichages(); //clignotement volontaire (indique que l'écriture a bien été effectuée)
  1734. delay(500);
  1735. }
  1736. }
  1737.  
  1738. void test_clic_bt_close1() // referme la box de saisie couleur fond d'écran et réaffiche le vu-mètre
  1739. {
  1740. if(mode_affi != COUL) {return;}
  1741.  
  1742. uint16_t c1 = GRIS_6;
  1743. uint16_t c2 = JAUNE;
  1744.  
  1745. test_clic_boutons(&bt_close1 );
  1746.  
  1747. if (bt_close1.cliked)
  1748. {
  1749. bt_close1.cliked = false;
  1750. bt_close1.selected = true;
  1751. bt_close1.affiche(NOIR, VERT, 1);
  1752.  
  1753. mode_affi = VUM;
  1754. init_affichages();
  1755. }
  1756. }
  1757.  
  1758.  
  1759. void affi_valeurs_RGB() // les 3 nombres près des boutons
  1760. {
  1761. uint16_t x = x0_choix_couleur;
  1762. //uint16_t y = y0_choix_couleur;
  1763. uint16_t z;
  1764. String s1;
  1765.  
  1766. TFT.setFreeFont(FF0); TFT.setTextColor(BLANC, NOIR);
  1767.  
  1768. s1 = String(cR);
  1769. z= bt_R_plus.y0;
  1770. TFT.fillRect(x+55, z+5, 20, 8, NOIR); // efface
  1771. TFT.drawString(s1, x+60, z+5);
  1772.  
  1773. s1 = String(cG);
  1774. z= bt_G_plus.y0;
  1775. TFT.fillRect(x+55, z+5, 20, 8, NOIR); // efface
  1776. TFT.drawString(s1, x+60, z+5);
  1777.  
  1778. s1 = String(cB);
  1779. z= bt_B_plus.y0;
  1780. TFT.fillRect(x+55, z+5, 20, 8, NOIR); // efface
  1781. TFT.drawString(s1, x+60, z+5);
  1782. }
  1783.  
  1784.  
  1785.  
  1786. void test_clic_1_bouton_couleur(TOUCH_BOUTON *bouton_i, uint8_t *cX, int8_t d )
  1787. {
  1788. uint16_t c1 = GRIS_3;
  1789. uint16_t c2 = BLANC;
  1790.  
  1791. uint16_t x = x0_choix_couleur;
  1792. uint16_t y = y0_choix_couleur;
  1793.  
  1794. test_clic_boutons(bouton_i);
  1795. if (bouton_i->cliked)
  1796. {
  1797. bouton_i->affiche(c1, c2, 1);
  1798. bouton_i->cliked=false;
  1799. bouton_i->selected=false;
  1800. int v = *cX;
  1801. v += d;
  1802. if(v<0) {v=0;}
  1803. if(v>64) {v=64;}
  1804. *cX = v;
  1805. String s1 = String(*cX );
  1806.  
  1807. uint16_t z= bouton_i->y0;
  1808. TFT.fillRect(x+55, z+5, 20, 8, NOIR); // efface
  1809. TFT.setFreeFont(FF0); TFT.setTextColor(BLANC, NOIR);
  1810. TFT.drawString(s1, x+60, z+5);
  1811. delay(100);
  1812. bouton_i->affiche(c1, c2, 1);
  1813.  
  1814. uint16_t couleur; // RGB_565
  1815. couleur = ( (cR<<11) | (cG<<5) | (cB) );
  1816. couleur_fond_ecran = couleur;
  1817. s1 = String(couleur);
  1818. TFT.fillRect(x+5, y+60, 40, 10, NOIR);
  1819. TFT.drawString(s1, x+5, y+60);
  1820.  
  1821. TFT.fillRoundRect(x+80, y+10, 40, 40, 5, couleur_fond_ecran); // grand carré de test couleur
  1822. }
  1823. }
  1824.  
  1825. void test_clic_boutons_couleurs()
  1826. {
  1827. if(mode_affi != COUL) {return;}
  1828.  
  1829. test_clic_1_bouton_couleur(&bt_R_plus, &cR, 1);
  1830. test_clic_1_bouton_couleur(&bt_R_moins, &cR, -1);
  1831.  
  1832. test_clic_1_bouton_couleur(&bt_G_plus, &cG, 1);
  1833. test_clic_1_bouton_couleur(&bt_G_moins, &cG, -1);
  1834.  
  1835. test_clic_1_bouton_couleur(&bt_B_plus, &cB, 1);
  1836. test_clic_1_bouton_couleur(&bt_B_moins, &cB, -1);
  1837. }
  1838.  
  1839.  
  1840.  
  1841. void test_clic_bouton_mute()
  1842. {
  1843. test_clic_boutons(&bt_mute );
  1844. bt_mute.affiche(NOIR, ROUGE, 1);
  1845. delay(100);
  1846. if (bt_mute.cliked)
  1847. {
  1848. bt_mute.cliked = false;
  1849. mute = ! mute;
  1850. Set_Mute(mute); // fonction située dans le fichier 'driverTEF6686_628.h'
  1851. bt_mute.selected = mute;
  1852. bt_mute.affiche(NOIR, ROUGE, 1);
  1853. if (! mute) {Tune_Frequence(frequence);}
  1854. delay(500);
  1855. }
  1856. }
  1857.  
  1858.  
  1859. void test_clic_bouton_Sleep()
  1860. {
  1861. test_clic_boutons(&bt_sleep );
  1862. //bt_sleep.affiche(NOIR, ROUGE, 1);
  1863. //delay(100);
  1864. if (bt_sleep.cliked)
  1865. {
  1866. bt_sleep.cliked = false;
  1867. bt_sleep.selected = true;
  1868. bt_sleep.affiche(NOIR, ROUGE, 1);
  1869. delay(100);
  1870.  
  1871. EEPROM.writeUInt(EEPROM_adrs_freq, frequence); // write 1 mot de 16 bits soit 2 octets
  1872.  
  1873. Serial.print("mode_s ici1: "); Serial.println(mode_s);
  1874. EEPROM.writeByte(EEPROM_adrs_mode, mode_s); // write 1 octet
  1875. EEPROM.commit();
  1876.  
  1877. delay(100);
  1878. esp_deep_sleep_start();
  1879. }
  1880. }
  1881.  
  1882.  
  1883. void test_clic_bouton_test()
  1884. {
  1885. test_clic_boutons(&bt_test );
  1886. bt_test.affiche(GRIS_2, VERT, 1);
  1887. delay(100);
  1888. if (bt_test.cliked)
  1889. {
  1890. bt_test.cliked = false;
  1891. bt_test.selected = true;
  1892. bt_test.affiche(GRIS_2, VERT, 1);
  1893.  
  1894. write_TFT_on_SDcard();
  1895.  
  1896. delay(100);
  1897. bt_test.selected = false;
  1898. bt_test.affiche(GRIS_2, VERT, 1);
  1899. }
  1900. }
  1901.  
  1902. void EE_RAZ()
  1903. {
  1904. boolean valider = false; // <-- ecrire "= true" pour rendre l'effacement possible
  1905. // (évite tout effacement accidentel et donc perte de centaines de fréquences...)
  1906.  
  1907. if(valider == false)
  1908. {
  1909. TFT.fillScreen(NOIR);
  1910. TFT.setFreeFont(FM9);
  1911. TFT.drawString("FONCTION VOLONTAIREMENT", 50, 120);
  1912. TFT.drawString("INACTIVE", 50, 140);
  1913. TFT.drawString("VOIR LE CODE SOURCE", 50, 160);
  1914. TFT.drawString("void EE_RAZ()", 50, 180);
  1915. delay(3000);
  1916. //setup();
  1917. init_affichages();
  1918. return;
  1919. }
  1920.  
  1921. // efface le contenu del'EEPROM, partie data fréquences, sans toucher aux 100 premiers octets
  1922. Serial.println("debut RAZ EEPROM");
  1923. for(uint16_t n = 0; n<1200; n+=4 ) // 300 x 4 bytes // OK
  1924. {
  1925. uint32_t valeur1;
  1926. valeur1 = 0;
  1927. EEPROM.writeUInt(100+n, valeur1); // les 100 premiers octets sont réservés (par moi)
  1928. }
  1929. EEPROM.commit();
  1930. Serial.println("fin RAZ EEPROM");
  1931. }
  1932.  
  1933.  
  1934.  
  1935. void test_clic_bouton_EE_RAZ()
  1936. {
  1937. uint16_t c1 = NOIR;
  1938. uint16_t c2 = VERT;
  1939.  
  1940. test_clic_boutons(&bt_EE_RAZ );
  1941. if(bt_EE_RAZ.cliked)
  1942. {
  1943. bt_EE_RAZ.cliked = false;
  1944. bt_EE_RAZ.selected = false;
  1945. bt_EE_RAZ.affiche(ROUGE, c1, 1);
  1946.  
  1947. EE_RAZ();
  1948. //EE_to_serial();
  1949. }
  1950. }
  1951.  
  1952.  
  1953. uint16_t EE_find_1ere_mem_libre(uint16_t adr0) // travaille directement sur l'EEPROM (en lecture uniquement!)
  1954. {
  1955. Serial.println("EE_find_1ere_mem_libre");
  1956. uint16_t n =0;
  1957. uint16_t adresse_lue;
  1958. uint32_t valeur_lue;
  1959. boolean ok = false;
  1960. while ((n<50) && (ok == false))
  1961. {
  1962. n += 4;
  1963. adresse_lue = adr0 + n;
  1964. valeur_lue = EEPROM.readUInt(adresse_lue); // 4 octets
  1965. Serial.print("valeur lue: "); Serial.println(valeur_lue);
  1966. if (valeur_lue == 0) {ok = true;}
  1967. }
  1968. Serial.print("trouve: "); Serial.println(n);
  1969. return adresse_lue;
  1970. }
  1971.  
  1972. boolean EE_find_if_present(uint16_t adr0, uint32_t F_i) // travaille directement sur l'EEPROM (en lecture uniquement!)
  1973. {
  1974. Serial.println("EE_find_if_present");
  1975. uint16_t n =0;
  1976. uint16_t adresse_lue;
  1977. uint32_t valeur_lue;
  1978. boolean ok = false;
  1979. while ((n<100) && (ok == false))
  1980. {
  1981. n += 4;
  1982. adresse_lue = adr0 + n;
  1983. valeur_lue = EEPROM.readUInt(adresse_lue); // 4 octets
  1984. if (valeur_lue == F_i) {ok = true;}
  1985. }
  1986. return ok;
  1987. }
  1988.  
  1989.  
  1990.  
  1991. void test_clic_bouton_EE_write()
  1992. {
  1993. uint16_t c1 = GRIS_6;
  1994. uint16_t c2 = VERT;
  1995.  
  1996. test_clic_boutons(&bt_EE_write );
  1997. if(bt_EE_write.cliked)
  1998. {
  1999. Serial.println("--------------------------------");
  2000. Serial.println("bouton_EE_write clic");
  2001.  
  2002. bt_EE_write.cliked = false;
  2003. bt_EE_write.selected = false;
  2004. bt_EE_write.affiche(GRIS_3, c1, 1);
  2005. delay (300);
  2006. bt_EE_write.cliked = false;
  2007. bt_EE_write.selected = false;
  2008. bt_EE_write.affiche(c1, c2, 1); // fugitif
  2009.  
  2010. //TFT.drawString("WRITE !", 5, 120);
  2011. //TFT.fillRect(5, 120, 50, 30, NOIR); // efface
  2012.  
  2013. uint16_t adr0;
  2014. uint16_t m0;
  2015. if (bande_SW)
  2016. {
  2017. adr0 = groupe_SW.adr_0;
  2018. m0 = EE_find_1ere_mem_libre(adr0);
  2019. }
  2020. if (bande_FM)
  2021. {
  2022. adr0 = groupe_FM.adr_0;
  2023. m0 = EE_find_1ere_mem_libre(adr0);
  2024. }
  2025. if (bande_AIR)
  2026. {
  2027. adr0 = groupe_AIR.adr_0;
  2028. m0 = EE_find_1ere_mem_libre(adr0);
  2029. }
  2030.  
  2031. if( ! EE_find_if_present(adr0, frequence)) // pour éviter les doublons
  2032. {
  2033. Serial.println("EEPROM.writeUInt");
  2034. Serial.print("m0="); Serial.println(m0);
  2035. Serial.print("frequence="); Serial.println(frequence);
  2036.  
  2037. EEPROM.writeUInt(m0, frequence);
  2038. EEPROM.commit();
  2039. delay(500);
  2040. load_GRP_FREQ_EEPROM();
  2041. }
  2042. else
  2043. {
  2044. Serial.print("F=");
  2045. Serial.print(frequence);
  2046. Serial.println(" presente, NO write");
  2047. }
  2048. Serial.println("--------------------------------");
  2049. }
  2050. }
  2051.  
  2052.  
  2053.  
  2054. void test_clic_bouton_EE_read()
  2055. {
  2056. uint16_t c1 = GRIS_6;
  2057. uint16_t c2 = VERT;
  2058.  
  2059. test_clic_boutons(&bt_EE_read );
  2060. if(bt_EE_read.cliked)
  2061. {
  2062. bt_EE_read.cliked = false;
  2063. bt_EE_read.selected = false;
  2064. bt_EE_read.affiche(GRIS_3, c1, 1);
  2065.  
  2066. delay (300);
  2067. bt_EE_read.cliked = false;
  2068. bt_EE_read.selected = false;
  2069. bt_EE_read.affiche(c1, c2, 1); // fugitif
  2070.  
  2071.  
  2072. }
  2073. }
  2074.  
  2075.  
  2076. void test_clic_boutons_MODE() // FREQ - MEM
  2077. {
  2078. uint16_t c1 = NOIR;
  2079. uint16_t c2 = VERT;
  2080. uint16_t c3 = JAUNE;
  2081.  
  2082. bt_mode_FRQ.cliked = false;
  2083. bt_mode_MEM.cliked = false;
  2084.  
  2085. test_clic_boutons(&bt_mode_FRQ );
  2086. if (bt_mode_FRQ.cliked) // les boutons sont exclusifs
  2087. {
  2088. mode_s = _FRQ;
  2089. bt_mode_FRQ.selected = true;
  2090. bt_mode_MEM.selected = false;
  2091. affiche_frequence(frequence);
  2092. efface_numero_frq();
  2093. }
  2094.  
  2095. test_clic_boutons(&bt_mode_MEM );
  2096. if (bt_mode_MEM.cliked)
  2097. {
  2098. mode_s = _MEM;
  2099. bt_mode_MEM.selected = true;
  2100. bt_mode_FRQ.selected = false;
  2101. //affiche_box_FRQ(JAUNE);
  2102. affiche_frequence(frequence);
  2103. }
  2104.  
  2105. bt_mode_FRQ.affiche(c1, c2, 1);
  2106. bt_mode_MEM.affiche(c1, c3, 1);
  2107. }
  2108.  
  2109.  
  2110. void test_clic_boutons_BANDE() // SW, FM, AIR
  2111. {
  2112. uint16_t c1 = NOIR;
  2113. uint16_t c2 = VERT;
  2114.  
  2115. bt_SW.cliked = false;
  2116. bt_FM.cliked = false;
  2117. bt_AIR.cliked = false;
  2118.  
  2119. test_clic_boutons(&bt_SW );
  2120. if (bt_SW.cliked)
  2121. {
  2122. TFT.fillRect(x0_box_info+2, y0_box_info+2, 175, 12, couleur_fond_ecran); // efface
  2123. Serial.println("bt_SW.cliked");
  2124. bande_active = SW;
  2125. bt_SW.selected = true;
  2126. bt_FM.selected = false; // les boutons sont exclusifs
  2127. bt_AIR.selected = false;
  2128. efface_numero_frq();
  2129.  
  2130. boutons_preset_set_frequences();
  2131. clic_logiciel_bouton(&bt_station1);
  2132. }
  2133.  
  2134. test_clic_boutons(&bt_FM );
  2135. if (bt_FM.cliked)
  2136. {
  2137. Serial.println("bt_FM.cliked");
  2138. bande_active = FM;
  2139. bt_FM.selected = true;
  2140. bt_SW.selected = false;
  2141. bt_AIR.selected = false;
  2142. efface_numero_frq();
  2143.  
  2144. boutons_preset_set_frequences();
  2145. clic_logiciel_bouton(&bt_station1);
  2146. }
  2147.  
  2148. test_clic_boutons(&bt_AIR );
  2149. if (bt_AIR.cliked)
  2150. {
  2151. TFT.fillRect(x0_box_info+2, y0_box_info+2, 175, 12, couleur_fond_ecran); // efface
  2152. Serial.println("bt_AIR.cliked");
  2153. bande_active = AIR;
  2154. bt_AIR.selected = true;
  2155. bt_SW.selected = false;
  2156. bt_FM.selected = false;
  2157. efface_numero_frq();
  2158.  
  2159. boutons_preset_set_frequences();
  2160. clic_logiciel_bouton(&bt_station1);
  2161. }
  2162.  
  2163. bt_SW.affiche(c1, c2, 1);
  2164. bt_FM.affiche(c1, c2, 1);
  2165. bt_AIR.affiche(c1, c2, 1);
  2166. }
  2167.  
  2168.  
  2169.  
  2170. void test_1_bouton_preset(TOUCH_BOUTON_PRESET *bouton_i)
  2171. {
  2172. uint16_t c1 = GRIS_5;
  2173. uint16_t c2 = GRIS_1;
  2174. uint16_t c3 = JAUNE;
  2175.  
  2176. //bouton_i->affiche(c1, c2, 1);
  2177. if (mode_affi == VUM) { bouton_i->affiche(c1, c2, 1); }
  2178.  
  2179. test_clic_boutons(bouton_i );
  2180. if (bouton_i->cliked)
  2181. {
  2182. bouton_i->cliked = false;
  2183. bouton_i->selected = true;
  2184.  
  2185. bouton_i->affiche(c1, c2, 1);
  2186.  
  2187. if (mode_affi == VUM)
  2188. {
  2189. mode_s = _MEM;
  2190. bt_mode_MEM.selected = true;
  2191. bt_mode_FRQ.selected = false;
  2192. efface_numero_frq();
  2193.  
  2194. bt_mode_MEM.affiche(c1, c3, 1);
  2195. bt_mode_FRQ.affiche(c1, c2, 1);
  2196.  
  2197. frequence = bouton_i->frequence;
  2198. affiche_frequence(frequence);
  2199. TFT.fillRoundRect(10, 3, 100, 10, 3, c1); // efface
  2200. TFT.setTextColor(JAUNE, NOIR);
  2201. TFT.drawString(bouton_i->nom, 10, 4);
  2202. Tune_Frequence(bouton_i->frequence);
  2203.  
  2204. bt_mute.selected = false;
  2205. bt_mute.affiche(NOIR, ROUGE, 1);
  2206. }
  2207.  
  2208. if (mode_affi == COUL)
  2209. {
  2210. //uint16_t couleur;
  2211. //couleur = bouton_i->couleur;
  2212. couleur_fond_ecran = bouton_i->couleur;
  2213. init_affichages();
  2214. }
  2215. //bouton_i->affiche(c1, c2, 1);
  2216. }
  2217.  
  2218. }
  2219.  
  2220.  
  2221. void deselect_boutons_presets()
  2222. {
  2223. bt_station1.selected = false;
  2224. bt_station2.selected = false;
  2225. bt_station3.selected = false;
  2226. bt_station4.selected = false;
  2227. bt_station5.selected = false;
  2228. bt_station6.selected = false;
  2229. bt_station7.selected = false;
  2230. bt_station8.selected = false;
  2231. }
  2232.  
  2233.  
  2234.  
  2235. void test_boutons_presets()
  2236. {
  2237. uint16_t c1 = NOIR;
  2238. uint16_t c2 = BLEU;
  2239.  
  2240. deselect_boutons_presets();
  2241.  
  2242. test_1_bouton_preset(&bt_station1);
  2243. test_1_bouton_preset(&bt_station2);
  2244. test_1_bouton_preset(&bt_station3);
  2245. test_1_bouton_preset(&bt_station4);
  2246. test_1_bouton_preset(&bt_station5);
  2247. test_1_bouton_preset(&bt_station6);
  2248. test_1_bouton_preset(&bt_station7);
  2249. test_1_bouton_preset(&bt_station8);
  2250.  
  2251. deselect_boutons_presets();
  2252.  
  2253. }
  2254.  
  2255.  
  2256. void affiche_signal(uint16_t x, uint16_t y, uint16_t dx, int16_t valeur)
  2257. {
  2258. TFT.fillRect(x, y, dx, 8, NOIR); // efface
  2259. if(valeur<0) {valeur =0;}
  2260. if(valeur > dx) {valeur = dx;}
  2261. TFT.drawRect(x, y, dx, 5, couleur_traits);
  2262. TFT.fillRect(x, y, valeur, 5, JAUNE);
  2263. }
  2264.  
  2265.  
  2266.  
  2267. void affiche_1_bargraph(uint16_t x, uint16_t y, uint16_t dx, int16_t valeur, uint16_t couleur)
  2268. {
  2269. TFT.fillRect(x, y, dx+40, 8, NOIR); // efface
  2270. TFT.drawString(String(valeur), x, y);
  2271.  
  2272. if(valeur<0) {valeur =0;}
  2273. if(valeur > dx) {valeur = dx;}
  2274. TFT.drawRect(x+40, y, dx, 5, couleur_traits);
  2275. TFT.drawRect(x+40, y, valeur, 5, couleur);
  2276. }
  2277.  
  2278.  
  2279. void affiche_bars_graph()
  2280. {
  2281. affiche_1_bargraph(170, 150, 100, level/10, VERT);
  2282. affiche_1_bargraph(170, 160, 100, usn, JAUNE);
  2283. affiche_1_bargraph(170, 170, 100, wam, BLEU_CLAIR);
  2284. affiche_1_bargraph(170, 180, 100, offset, BLANC);
  2285. }
  2286.  
  2287.  
  2288. String int_to_hex(uint16_t nb)
  2289. {
  2290. char symb[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
  2291. uint8_t A = (nb & 0b1111000000000000) >>12;
  2292. uint8_t B = (nb & 0b0000111100000000) >>8;
  2293. uint8_t C = (nb & 0b0000000011110000) >>4;
  2294. uint8_t D = (nb & 0b0000000000001111);
  2295. String s1 = String(symb[A]) + String(symb[B]) + String(symb[C]) + String(symb[D]) ;
  2296. return s1;
  2297. }
  2298.  
  2299.  
  2300.  
  2301. void traite_signal_RDS()
  2302. {
  2303. Get_RDS_Data ( &status, &A_block, &B_block, &C_block, &D_block, &dec_error);
  2304. /*
  2305. A_Block always contains the 16-bit program identifier.
  2306. The first 11 bits (bits 15–5) of block 2 are also the same in all groups.
  2307. La Liste des codes RDS autorisés se trouve ici : https://www.csa.fr/maradiofm/radiords_tableau
  2308. pour les autres blocks, voir :
  2309. https://en.wikipedia.org/wiki/Radio_Data_System
  2310. (c'est sans doute logique mais terriblement indigeste !!!)
  2311. */
  2312.  
  2313. TFT.fillRect(x0_box_info+2, y0_box_info+2, 175, 12, couleur_fond_ecran); // efface
  2314. String s1 = int_to_hex(A_block);
  2315.  
  2316. String s2, s3;
  2317. TFT.setTextColor(BLANC, GRIS_5);
  2318.  
  2319. for(int n = 0; n<=nb_stations_RDS-1; n++)
  2320. {
  2321. s2 = codesRDS[n];
  2322. //Serial.println(s2);
  2323. s3 = s2.substring(0, 4);
  2324.  
  2325. if (s3 == s1)
  2326. {
  2327. TFT.drawString(s2, x0_box_info+5, y0_box_info +4);
  2328. return; // on ne continue pas à boucler si trouvé
  2329. }
  2330. else if (n == nb_stations_RDS-1) // pas trouvé...
  2331. {
  2332. TFT.drawString(s1, x0_box_info+5, y0_box_info +4);
  2333. return;
  2334. }
  2335. }
  2336. }
  2337.  
  2338.  
  2339. void loop()
  2340. {
  2341. if (ts.tirqTouched() && ts.touched())
  2342. {
  2343. TS_Point p = ts.getPoint();
  2344. printTouchToDisplay(p);
  2345.  
  2346. test_clic_6_boutons_frq();
  2347. test_clic_boutons_plus_moins();
  2348. test_clic_bouton_mute();
  2349. test_clic_bouton_Sleep();
  2350. test_clic_bouton_test();
  2351. test_clic_boutons_MODE();
  2352. test_clic_boutons_BANDE();
  2353. test_boutons_presets();
  2354.  
  2355. uint8_t n_touch = numPad1.test_clic();
  2356. traite_touches_pad(n_touch);
  2357.  
  2358. test_clic_bouton_EE_RAZ();
  2359. test_clic_bouton_EE_write();
  2360. test_clic_bouton_EE_read();
  2361. test_clic_bt_affi_box_couleurs();
  2362. test_clic_boutons_couleurs();
  2363. test_clic_bt_close1();
  2364. test_clic_bt_RST_affi();
  2365. test_clic_bt_coul_to_EEPROM();
  2366. }
  2367.  
  2368. // la limitation SW max = 28MHz est due au module TEF6686 lui-même
  2369. if (frequence >= 138000) {frequence = 138000;} //138 MHz limite à cause SW max = 28MHz et conv AirBand = 110 MHz
  2370. if (frequence < 1500) {frequence = 1500;} // 1.5 MHz
  2371.  
  2372.  
  2373. if (compteur1 >= 5)
  2374. {
  2375. compteur1 =0;
  2376. uint8_t module;
  2377. if(bande_active == FM) {module = 32;} else {module = 33;}
  2378. Get_Quality( module, &status, &level, &usn, &wam, &offset, &bandwidth, &mod, &snr );
  2379.  
  2380. float signal_sur_bruit = level - 1.5 * usn; // marche à peu près bien pour la FM.
  2381. // toutefois additionner une valeur linéaire avec une autre logarithmique... pas top !
  2382. // faut que je vois ça de plus près !
  2383.  
  2384. float diff = signal_sur_bruit - position_aiguille;
  2385. if(diff > 30.0) {diff = 30.0;}
  2386. if(diff < -30.0) {diff = -30.0;} // évite une trop grande réaction au sortir du mode 'mute'
  2387. // supprime les tremblements de l'aiguille
  2388. position_aiguille += diff / 10.0;
  2389.  
  2390. //affiche_bars_graph();
  2391. affiche_signal(170, 90, 60, mod/2);
  2392. if ((mode_affi == VUM) && (! mute) ) { plotAiguille(position_aiguille/6.0); }
  2393. if ((mode_affi == VUM) && (mute) ) { plotAiguille(0); }
  2394. }
  2395.  
  2396. if (compteur2 >= 100)
  2397. {
  2398. compteur2 =0;
  2399.  
  2400. if(bande_active == FM) {traite_signal_RDS();}
  2401.  
  2402. /*
  2403. TFT.drawString(
  2404. String(A_block) + " " +
  2405. String(B_block) + " " +
  2406. String(C_block) + " " +
  2407. String(D_block) + " ", x0_box_info+5, y0_box_info +4);
  2408. */
  2409. }
  2410.  
  2411. #ifdef _SD_CARD
  2412. if (compteur3 == 2000)
  2413. {
  2414. write_TFT_on_SDcard(); // attention : incompatible avec le TOUCHPAD
  2415. }
  2416. #endif
  2417.  
  2418. delay(10);
  2419. compteur1++;
  2420. compteur2++;
  2421. compteur3++;
  2422. }
  2423.  
  2424.  
  2425. /** ***************************************************************************************
  2426. CLASS TOUCH_BOUTON // affiche un nombre ou un petit texte dans un rectangle
  2427. ainsi que (en plus petit) deux valeurs supplémentaires, par ex: les valeurs mini et maxi
  2428. ********************************************************************************************/
  2429.  
  2430. // Constructeur
  2431. TOUCH_BOUTON::TOUCH_BOUTON()
  2432. {
  2433.  
  2434. }
  2435.  
  2436. // Constructeur
  2437. TOUCH_BOUTON_PRESET::TOUCH_BOUTON_PRESET()
  2438. {
  2439.  
  2440. }
  2441.  
  2442.  
  2443.  
  2444. void TOUCH_BOUTON::init(uint16_t xi, uint16_t yi, uint16_t dxi, uint16_t dyi, uint16_t dri)
  2445. {
  2446. x0 = xi;
  2447. y0 = yi;
  2448. dx = dxi;
  2449. dy = dyi;
  2450. dr = dri;
  2451.  
  2452. cliked = false;
  2453. selected = false;
  2454. }
  2455.  
  2456.  
  2457.  
  2458. void TOUCH_BOUTON::affiche(uint16_t coul_fill_unselect, uint16_t coul_fill_select, uint8_t n_font)
  2459. {
  2460. //uint16_t c1 = NOIR;
  2461. uint16_t couleur_contour = GRIS_5;
  2462. //uint16_t couleur_texte = BLANC);
  2463.  
  2464. if(selected)
  2465. {
  2466. TFT.fillRoundRect(x0, y0, dx, dy, dr, coul_fill_select);
  2467. TFT.setTextColor(NOIR);
  2468. }
  2469. else
  2470. {
  2471. TFT.fillRoundRect(x0, y0, dx, dy, dr, coul_fill_unselect); // efface
  2472. TFT.drawRoundRect(x0, y0, dx, dy, dr, couleur_contour); // retrace juste le contour
  2473. TFT.setTextColor(BLANC);
  2474. }
  2475.  
  2476. //FM9 FMB9 FSS9... voir le fichier Free_Fonts.h
  2477. if (n_font == 1) { TFT.setFreeFont(FF0); }
  2478. if (n_font == 2) { TFT.setFreeFont(FM9); }
  2479. if (n_font == 3) { TFT.setFreeFont(FMB9); }
  2480. if (n_font == 4) { TFT.setFreeFont(FSS9); }
  2481.  
  2482. TFT.drawString(s, x0+5, y0+5);
  2483.  
  2484. }
  2485.  
  2486. /** ***************************************************************************************
  2487. CLASS NUMPAD
  2488. ********************************************************************************************/
  2489. // Constructeur
  2490. NUM_PAD::NUM_PAD()
  2491. {
  2492. pad[0] = bt_num0;
  2493. pad[1] = bt_num1;
  2494. pad[2] = bt_num2;
  2495. pad[3] = bt_num3;
  2496. pad[4] = bt_num4;
  2497. pad[5] = bt_num5;
  2498. pad[6] = bt_num6;
  2499. pad[7] = bt_num7;
  2500. pad[8] = bt_num8;
  2501. pad[9] = bt_num9;
  2502. }
  2503.  
  2504.  
  2505. void NUM_PAD::init(uint16_t xi, uint16_t yi, boolean fond) // si fond =false, ne resessine que les boutons
  2506. {
  2507. x0 = xi;
  2508. y0 = yi;
  2509. int x, y;
  2510. int dx = 25; // taille x d'une touche
  2511. int dy = 23; // taille y d'une touche
  2512.  
  2513. if(fond == true) {TFT.fillRect(x0, y0, 3*dx +6, 4*dy +7, NOIR);}
  2514.  
  2515. uint16_t c1 = GRIS_5;
  2516. uint16_t c2 = JAUNE;
  2517.  
  2518. x = x0+2;
  2519. y = y0+2;
  2520.  
  2521. for(uint8_t n =1; n<10; n++)
  2522. {
  2523. pad[n].init(x, y, dx, dy, 3);
  2524. pad[n].s=String(n);
  2525. pad[n].affiche(c1, c2, 2);
  2526. x += dx+1;
  2527. if (x > (x0 + 3*dx)) {x = x0+2; y += dy+1; }
  2528. }
  2529. pad[0].init(x, y, dx, dy, 3); pad[0].s="0"; pad[0].affiche(c1, c2, 2); x += dx+1;
  2530. bt_point.init(x, y, dx, dy, 3); bt_point.s="."; bt_point.affiche(c1, c2, 2);
  2531.  
  2532. x += dx+1;
  2533. bt_ok.init(x, y, dx, dy, 3); bt_ok.s="ok";
  2534. bt_ok.affiche(c1, c2, 1);
  2535. }
  2536.  
  2537.  
  2538. uint8_t NUM_PAD::test_clic()
  2539. {
  2540. // zone des boutons du claver
  2541. if ( (( x_touch > x0) && (x_touch < x0 + 100)) && (( y_touch > y0) && (y_touch < y0 + 130)))
  2542. {
  2543. uint8_t num_touche =0;
  2544.  
  2545. for(uint8_t n = 0; n<10; n++)
  2546. {
  2547. test_clic_boutons(&pad[n] ); if(pad[n].cliked) {num_touche=n; n_appui ++;}
  2548. }
  2549.  
  2550. test_clic_boutons(&bt_point ); if(bt_point.cliked) {num_touche=254; } // bouton "."
  2551. test_clic_boutons(&bt_ok ); if(bt_ok.cliked) {num_touche=255; n_appui ++;} // bouton "ok"
  2552. delay(100);
  2553. init(x0, y0, false); // 'false' évite le clignotement lorsqu'on repeint le fond noir
  2554.  
  2555. return num_touche;
  2556. }
  2557. return 253;
  2558. }
  2559.  
  2560.  
  2561. /** ***************************************************************************************
  2562. CLASS GROUPE_FREQUENCES // objet image d'un bloc mémoire en EEPROM
  2563. permet diverses manipulations en RAM (tri...) sans toucher à l'EEPROM
  2564. ********************************************************************************************/
  2565.  
  2566. // Constructeur
  2567. GROUPE_FREQUENCES::GROUPE_FREQUENCES()
  2568. {
  2569.  
  2570. }
  2571.  
  2572.  
  2573. void GROUPE_FREQUENCES::load_bloc()
  2574. {
  2575. // partie données de fréquences (adrs >100)
  2576. Serial.println("load_bloc()");
  2577. //Serial.print("adr_0= "); Serial.println(adr_0);
  2578. uint32_t valeur_lue;
  2579. for(uint16_t n = 0; n<100; n++ ) // chaque uint32_t lu = 4 Bytes
  2580. {
  2581. valeur_lue = EEPROM.readUInt(adr_0 + n*4); // 4 octets
  2582. G_freq[n]=valeur_lue;
  2583. }
  2584. }
  2585.  
  2586.  
  2587. void GROUPE_FREQUENCES::tri_bloc()
  2588. {
  2589. Serial.println("tri_block()");
  2590. // tri par bulles
  2591.  
  2592. uint32_t F1=0, F2=0;
  2593. uint32_t Fi;
  2594. uint16_t i_max = 100;
  2595. uint16_t p_max = 100;
  2596.  
  2597. for(uint16_t p=0; p<p_max; p++)
  2598. {
  2599. for(int n=0; n<i_max-1; n++)
  2600. {
  2601. F1=G_freq[n];
  2602. F2=G_freq[n+1];
  2603.  
  2604. if(F1 > F2)
  2605. {
  2606. Fi = G_freq[n];
  2607. G_freq[n] = G_freq[n+1];
  2608. G_freq[n+1] = Fi;
  2609. }
  2610. }
  2611. }
  2612.  
  2613. // compte le nombre de fréquences != 0
  2614. uint16_t nombre =0;
  2615. for(uint16_t n = 0; n<100; n++ )
  2616. {
  2617. F1 = G_freq[n];
  2618. if(F1 != 0) { nombre++; }
  2619. }
  2620. nb_freq = nombre;
  2621.  
  2622. // recherche première fréquence non nulle
  2623. uint16_t n2=0;
  2624. F1 =0;
  2625. while ((F1==0) && (n2<100))
  2626. {
  2627. F1=G_freq[n2];
  2628. n2++;
  2629. }
  2630. adr_1ere_frq = n2-1;
  2631. }
  2632.  
  2633.  
  2634. void GROUPE_FREQUENCES::bloc_to_serial() // pour tests, avec CuteCom sous Linux
  2635. {
  2636. Serial.println("bloc_to_serial()");
  2637. uint32_t valeur_lue;
  2638. uint16_t nombre =0;
  2639. for(uint16_t n = 0; n<100; n++ )
  2640. {
  2641. valeur_lue = G_freq[n];
  2642. if(valeur_lue != 0) // n'affiche pas les emplacements vides
  2643. {
  2644. nombre++;
  2645. Serial.println(valeur_lue);
  2646. }
  2647. }
  2648. Serial.print(nombre); Serial.println(" frequences");
  2649. Serial.print("adr 1ere Frq= "); Serial.println(adr_1ere_frq);
  2650. Serial.print("1ere Frq= "); Serial.println(G_freq[adr_1ere_frq]);
  2651.  
  2652. }
  2653.  
  2654.  

Voir plus bas "Documents" le code source complet comprenant les 'includes' et 'library' pour PlatformIO.
Remarque : Lorsque le module tuner TEF6686 n'est pas présent, n'est pas connecté physiquement à la carte CYD, le programme tourne très lentement, l'ESP32 passant son temps à attendre des réponses aux requêtes qu'il envoie sur le bus SPI.

7 Fichier source driver TEF6686_628.cpp

CODE SOURCE en C++
  1. /*************************************************************************************
  2. NOTE Silicium628
  3.  
  4. Les fonctions ci-dessous sont inspirées le plus directement possible de la lecture du pdf "TEF668X User Manuel" (NPX)
  5. Je n'utilise pas l'opérateur conditionnel ternaire ((condition) ? a : b) qui, bien que de haut niveau
  6. et permettant une écriture concise, ne facilite pas la lisibilité du programme.
  7.  
  8. **************************************************************************************/
  9.  
  10.  
  11. #include <Arduino.h>
  12. #include "Wire.h"
  13. #include "driverTEF6686_628.h"
  14.  
  15. byte addr_ISP = 0x64;
  16.  
  17. #define conv8to16(a) ((uint16_t)(((uint16_t)(*(a))) << 8 |((uint16_t)(*(a+1)))))
  18.  
  19.  
  20. void Write2(uint8_t *buf, uint8_t len)
  21. {
  22. Wire.beginTransmission(addr_ISP);
  23. for (int i = 0; i < len; i++)
  24. {
  25. Wire.write(*buf++);
  26. }
  27. Wire.endTransmission();
  28. }
  29.  
  30.  
  31. void Set_Cmd(uint8_t module, uint8_t cmd, int len, ...)
  32. {
  33. uint8_t i;
  34. uint8_t buf[31];
  35. uint16_t temp;
  36. va_list vArgs;
  37. va_start(vArgs, len);
  38. buf[0] = module;
  39. buf[1] = cmd;
  40. buf[2] = 1;
  41. for (i = 0; i < len; i++)
  42. {
  43. temp = va_arg(vArgs, int);
  44. buf[3 + i * 2] = (uint8_t)(temp >> 8);
  45. buf[4 + i * 2] = (uint8_t)temp;
  46. }
  47.  
  48. va_end(vArgs);
  49. Write2(buf, len * 2 + 3);
  50. }
  51.  
  52.  
  53. void Set_Volume(int v)
  54. {
  55. Set_Cmd(48, 11, 1, 0); //unmute (IMPORTANT sinon débute en mode MUTE...)
  56. int MapVolume = map(v, 0, 100, -599, 50);
  57. Set_Cmd(48, 10, 1, MapVolume); // module 48 : AUDIO = Audio processing
  58. }
  59.  
  60.  
  61.  
  62. void Tune_Frequence_FM(uint16_t F)
  63. {
  64. uint8_t octet_L, octet_H;
  65.  
  66. octet_L = F%256;
  67. octet_H = F/256;
  68.  
  69. Wire.beginTransmission(addr_ISP);
  70. Wire.write(0x20);
  71. Wire.write(0x01);
  72. Wire.write(0x01);
  73. Wire.write(0x00);
  74. Wire.write(0x01);
  75. Wire.write(octet_H);
  76. Wire.write(octet_L);
  77. Wire.endTransmission();
  78. }
  79.  
  80.  
  81. void Tune_Frequence_AM(uint16_t F)
  82. {
  83. uint8_t octet_L, octet_H;
  84.  
  85. octet_L = F%256;
  86. octet_H = F/256;
  87.  
  88. Wire.beginTransmission(addr_ISP);
  89. Wire.write(0x21);
  90. Wire.write(0x01);
  91. Wire.write(0x01);
  92. Wire.write(0x00);
  93. Wire.write(0x01);
  94. Wire.write(octet_H);
  95. Wire.write(octet_L);
  96. Wire.endTransmission();
  97. }
  98.  
  99.  
  100.  
  101. void Set_Mute(boolean M)
  102. {
  103. if (M == true) //radio standby mode (low-power mode without radio functionality)
  104. {
  105. Wire.beginTransmission(addr_ISP);
  106. Wire.write(0x40);
  107. Wire.write(0x01);
  108. Wire.write(0x01);
  109. Wire.endTransmission();
  110. }
  111. else // normal operation
  112. {
  113. Wire.beginTransmission(addr_ISP);
  114. Wire.write(0x40);
  115. Wire.write(0x01);
  116. Wire.write(0x00);
  117. Wire.endTransmission();
  118. }
  119. }
  120.  
  121.  
  122. void Set_no_AM_gain_reduction()
  123. {
  124. Wire.beginTransmission(addr_ISP);
  125. Wire.write(0x21); // 33
  126. Wire.write(0x0C); // 12
  127. Wire.write(0x01);
  128. Wire.write(0x00);
  129. Wire.write(0x00);
  130. Wire.endTransmission();
  131. }
  132.  
  133.  
  134. bool Tuner_WriteBuffer(uint8_t *buf, uint16_t len)
  135. {
  136. Wire.beginTransmission(0x64);
  137. for (uint16_t i = 0; i < len; i++) {Wire.write(buf[i]);}
  138. uint8_t r = Wire.endTransmission();
  139. delay(2);
  140. if(r==0) {return 1;}
  141. else {return 0;} // l'opérateur conditionnel ternaire (?) c'est pas mon truc !
  142. }
  143.  
  144.  
  145. bool Tuner_ReadBuffer(uint8_t *buf, uint16_t len)
  146. {
  147. Wire.requestFrom(0x64, len);
  148. if (Wire.available() == len)
  149. {
  150. for (uint16_t i = 0; i < len; i++) { buf[i] = Wire.read(); }
  151. return 1;
  152. }
  153. else {return 0;}
  154. }
  155.  
  156.  
  157. bool Tuner_Get_Cmd(uint8_t module, uint8_t cmd, uint8_t *receive, uint16_t len)
  158. {
  159. uint8_t buf[3];
  160. buf[0] = module;
  161. buf[1] = cmd;
  162. buf[2] = 1;
  163.  
  164. Tuner_WriteBuffer(buf, 3);
  165. return Tuner_ReadBuffer(receive, len); // 1 si ok, 0 si erreur
  166. }
  167.  
  168.  
  169. void Get_Quality (
  170. // paramètres passés par adresse (donc variables), tous actualisés par cette fonction
  171. // tous des uint16_t ou int16_t sauf le dernier int8_t
  172. //ce qui nous fait 7*2 +1 = 15 octets lus dans le module
  173. uint8_t module,
  174. uint16_t *status,
  175. int16_t *level,
  176. uint16_t *usn,
  177. uint16_t *wam,
  178. int16_t *offset,
  179. uint16_t *bandwidth,
  180. uint16_t *mod,
  181. int8_t *snr )
  182. {
  183. uint8_t buf[14];
  184.  
  185. uint16_t r = Tuner_Get_Cmd(module, 129, buf, sizeof(buf));
  186.  
  187. // voir datasheet du TEF6686
  188. // actualisation des paramètres
  189. *status = conv8to16(buf);
  190. *level = conv8to16(buf + 2);
  191. *usn = conv8to16(buf + 4); // noise
  192. *wam = conv8to16(buf + 6); // ‘wideband-AM’
  193. *offset = conv8to16(buf + 8); //radio frequency offset
  194. *bandwidth = conv8to16(buf + 10) / 10; // IF bandwidth
  195. *mod = conv8to16(buf + 12) / 10; // modulation detector
  196. if (*level < -200) *level = -200;
  197. if (*level > 1200) *level = 1200;
  198. *snr = int(0.46222375 * (float)(*level) / 10 - 0.082495118 * (float)(*usn) / 10) + 10;
  199. }
  200.  
  201.  
  202. bool Get_RDS_Data (
  203. uint16_t *status,
  204. uint16_t *A_block,
  205. uint16_t *B_block,
  206. uint16_t *C_block,
  207. uint16_t *D_block,
  208. uint16_t *dec_error)
  209. {
  210. uint8_t buf[12];
  211. uint8_t r = Tuner_Get_Cmd(32, 131, buf, sizeof(buf));
  212. *status = conv8to16(buf);
  213. *A_block = conv8to16(buf + 2);
  214. *B_block = conv8to16(buf + 4);
  215. *C_block = conv8to16(buf + 6);
  216. *D_block = conv8to16(buf + 8);
  217. *dec_error = conv8to16(buf + 10);
  218. return r;
  219. }

8 Fichier source main.h

CODE SOURCE en C++
  1. #include <Arduino.h>
  2.  
  3.  
  4. /** ***********************************************************************************
  5. CLASS VOYANT // sorte de LED qui peut s'allumer de différentes couleurs et afficher un mot
  6. ***************************************************************************************/
  7.  
  8. class TOUCH_BOUTON
  9. {
  10. public:
  11. uint16_t x0;
  12. uint16_t y0;
  13. uint16_t dx;
  14. uint16_t dy;
  15. uint16_t dr; // rayon de courbure des angles
  16. String s;
  17. boolean cliked;
  18. boolean selected;
  19.  
  20. TOUCH_BOUTON(); // constructeur
  21.  
  22. void init(uint16_t x, uint16_t y, uint16_t dx, uint16_t dy, uint16_t dri);
  23. void affiche(uint16_t coul_fill_unselect, uint16_t coul_fill_select, uint8_t n_font);
  24.  
  25. private:
  26.  
  27. };
  28.  
  29.  
  30. class TOUCH_BOUTON_PRESET : public TOUCH_BOUTON
  31. {
  32. public:
  33. uint32_t frequence;
  34. String nom;
  35. uint16_t couleur;
  36.  
  37. TOUCH_BOUTON_PRESET(); // constructeur
  38.  
  39. private:
  40.  
  41. };
  42.  
  43.  
  44. class NUM_PAD
  45. {
  46. public:
  47. uint8_t x0;
  48. uint8_t y0;
  49.  
  50. uint8_t dx;
  51. uint8_t dy;
  52.  
  53. TOUCH_BOUTON bt_num0, bt_num1, bt_num2, bt_num3, bt_num4, bt_num5, bt_num6, bt_num7, bt_num8, bt_num9;
  54. TOUCH_BOUTON pad[10];
  55.  
  56. TOUCH_BOUTON bt_point;
  57. TOUCH_BOUTON bt_ok;
  58.  
  59. NUM_PAD(); // constructeur
  60.  
  61. void init(uint16_t x0, uint16_t y0, boolean fond);
  62. uint8_t test_clic();
  63.  
  64. private:
  65.  
  66. };
  67.  
  68.  
  69. /** ***************************************************************************************
  70. CLASS GROUPE_FREQUENCES // objet image d'un bloc mémoire en EEPROM
  71. permet diverses manipulations en RAM (tri...) sans toucher à l'EEPROM
  72. ********************************************************************************************/
  73. class GROUPE_FREQUENCES
  74. {
  75. public:
  76. uint32_t G_freq[100];
  77. uint16_t adr_0; // adresse du groupe en EEPROM
  78. uint16_t adr_1ere_frq; // près un tri les F=0 se retrouvent en haut de liste. La 1ere F se retrouve donc bien plus bas
  79. uint16_t nb_freq; // nombre de fréquences !=0 enregistées
  80. uint16_t num_F_actuelle;
  81.  
  82. GROUPE_FREQUENCES(); // constructeur
  83.  
  84. void load_bloc(); // depuis l'EEPROM
  85. void bloc_to_serial(); // pour tests
  86. void tri_bloc(); // par valeur numérique des fréquences
  87.  
  88. private:
  89.  
  90. };
  91.  
  92.  
  93.  
  94. // ************************************************************************************
  95.  
  96.  
  97. void setup();
  98. void loop();
  99. void init_sprites();
  100. void affiche_unit(String s);
  101. void affiche_band(String s);
  102. void affiche_box_entete();
  103. void affiche_box_choix_couleur();
  104. void affi_valeurs_RGB();
  105. void affiche_box_FRQ(uint16_t couleur);
  106. void affiche_box_presets();
  107. void deselect_boutons_presets();
  108. void affiche_box_BANDE();
  109. void affiche_box_EEPROM();
  110. void affiche_box_FRQ(uint16_t couleur);
  111. void affiche_frequence(uint32_t frq); // en kHz
  112. void affiche_index_frq();
  113. void clic_logiciel_bouton(TOUCH_BOUTON *bouton_i);
  114. void dessine_VuMetre();
  115. void init_box_info();
  116.  
  117. //void Tune_Frequence_FM(uint16_t F);
  118. void Set_Volume(int v);

9 à suivre...

30 novembre 2025 :
Cet article est en cours de rédaction, je vais publier prochainement d'autres photos, des vidéos de l'utilisation, et plein de données techniques.

10 Documents

Un aperçu du code en cours de rédaction dans l'éditeur de VScode + PlatformIO

Code source en C++
30 novembre 2025 : Version du code source adaptée à l’éditeur VScode/PlatformIO
L'avantage par rapport à l'EDI Arduino c'est que ça encapsule toutes les dépendances et les bibliothèques nécessaires et dans la bonne version.

11 -

Liens...

72