/*
Radio TEF6686 perso
pour ESP32 Wroom + afficheur 2.8" TFT 240x320
pour la carte CYD (Cheap Yellow Display)
par Silicium628
*/
/* ************************************************************************************
CONCERNANT L'AFFICHAGE TFT
à placer dans le fichier User_Setup.h ( dans ~/Arduino/libraries/TFT_eSPI/ ):
#define ILI9341_2_DRIVER
****************************************************************************/
#include <Arduino.h>
#include "main.h"
#include "constantes_628.h"
#include "DSP_INIT_628.h"
#include "driverTEF6686_628.h"
#include <Free_Fonts.h>
#include "FS.h"
#include "SD.h"
#include "Wire.h"
#include <stdint.h>
#include "TFT_eSPI.h" // Hardware-specific library
#include "SPI.h"
#include "Free_Fonts.h"
#include "Digit_Font.h"
#include <XPT2046_Touchscreen.h>
#include <EEPROM.h>
// #define _SD_CARD // commenter cette ligne pour utiliser une SDcard; décommenter pour utiliser le Touchscreen
#define SPI_READ_FREQUENCY 16000000
// mem presets[EE_PRESETS_CNT];
#define EEPROM_SIZE 100+1200
#define EEPROM_adrs_couleur 0 // 2 octets pour un uint16_t
#define EEPROM_adrs_freq 2 // 4 octets pour un uint32_t
#define EEPROM_adrs_mode 6 // 1 octet pour un uint8_t
// 100 premiers bytes réservés pour sauvegarder diverses variables (Frq en cours par exemple...)
// reste 1200 bytes
// chaque fréquence est un uint_32 = 4 bytes
// 1200/4 = 300 fréquences mémorisée, c.a.d 3 bandes (SW, FM, AIR) de 100 freq chaque
// Remarque : il y a largement la possibikité d'en prévoir beaucoup plus !!
#define bande_SW (frequence > 1500) && (frequence < 28000)
#define bande_interdite1 (frequence > 28000) && (frequence < 88000)
#define bande_interdite2 (frequence > 108000) && (frequence < 118000)
#define bande_FM (frequence >= 88000) && (frequence < 108000)
#define bande_AIR (frequence >= 118000) && (frequence < 138000)
// XPT2046_Touchscreen // commenter cette ligne pour utiliser la fontion 'write_TFT_on_SDcard()'
#define XPT2046_IRQ 36
#define XPT2046_MOSI 32
#define XPT2046_MISO 39
#define XPT2046_CLK 25
#define XPT2046_CS 33
//sur le connecteur CN1 de la carte CYD sérigraphiée 'ESP32-2432S028';
//attention: ces valeurs ne sont pas celles par défaut pour SDA et SCL
const int GPIO_SDA = 27;
const int GPIO_SCL = 22;
#define High_16bto8b(a) ((uint8_t)((a) >> 8))
#define Low_16bto8b(a) ((uint8_t)(a ))
#define Convert8bto16b(a) ((uint16_t)(((uint16_t)(*(a))) << 8 |((uint16_t)(*(a+1)))))
String version = "12.3";
SPIClass mySpi = SPIClass(VSPI);
XPT2046_Touchscreen ts(XPT2046_CS, XPT2046_IRQ);
TFT_eSPI TFT = TFT_eSPI(); // Configurer le fichier User_Setup.h de la bibliothèque TFT_eSPI au préalable
TFT_eSprite sprite_frq = TFT_eSprite(&TFT);
//TFT_eSprite sprite_unit = TFT_eSprite(&TFT);
// pour afficheur TFT
const int _DX = 320;
const int _DY = 240;
float raddeg = M_PI/180.0;
float deg_to_rad = 2.0 * M_PI /360.0;
//***************************************************************************
//char var_array32[10];// 10 char + zero terminal - pour envoi par WiFi (because 2^32 -1 = 4294967295 -> 10 caractères)
// =====================================================================
TFT_eSprite Sprite_frq = TFT_eSprite(&TFT);
// la def de 'TFT_eSprite' se trouve dans ~/Arduino/libraries/TFT_eSPI/Extensions/Sprite.h
//TFT_eSPI::loadFont(FREQFONT.h);
uint16_t compteur1 = 0;
uint16_t compteur2 = 0;
uint16_t compteur3 = 0;
uint16_t compteur4 = 0;
uint8_t SDcardOk=0;
uint8_t do_wr_ecran_on_sd=0;
uint32_t frequence=1000;
uint32_t saut_freq;
uint32_t image_EE[300]; // permet le tri en RAM des fréquences sans toucher à l'EEPROM
GROUPE_FREQUENCES groupe_SW;
GROUPE_FREQUENCES groupe_FM;
GROUPE_FREQUENCES groupe_AIR;
String frequence_txt = "";
TOUCH_BOUTON bt_sleep;
TOUCH_BOUTON bt_mode_FRQ, bt_mode_MEM;
TOUCH_BOUTON bt_plus, bt_moins;
TOUCH_BOUTON bt_EE_RAZ, bt_EE_write, bt_EE_read;
TOUCH_BOUTON bt_1, bt_2, bt_3, bt_4, bt_5, bt_6; // au dessus des chiffres de la fréquence
// --- boutons choix couleur-------
TOUCH_BOUTON bt_affi_box_couleurs;
TOUCH_BOUTON bt_R_plus, bt_R_moins;
TOUCH_BOUTON bt_G_plus, bt_G_moins;
TOUCH_BOUTON bt_B_plus, bt_B_moins;
TOUCH_BOUTON bt_RST_affi;
TOUCH_BOUTON bt_close1;
TOUCH_BOUTON bt_coul_to_EEPROM;
TOUCH_BOUTON bt_test;
// ---------- numPad ------------
TOUCH_BOUTON bt_num0, bt_num1, bt_num2, bt_num3, bt_num4, bt_num5, bt_num6, bt_num7, bt_num8, bt_num9;
//TOUCH_BOUTON numPad[] = {bt_num0, bt_num1, bt_num2, bt_num3, bt_num4, bt_num5, bt_num6, bt_num7, bt_num8, bt_num9 };
NUM_PAD numPad1;
//TOUCH_BOUTON bt_point, bt_ok;
// -------------------------------
TOUCH_BOUTON bt_SW, bt_FM, bt_AIR;
TOUCH_BOUTON bt_mute;
TOUCH_BOUTON_PRESET bt_station1, bt_station2, bt_station3, bt_station4, bt_station5, bt_station6, bt_station7, bt_station8;
boolean mute = false;
enum MODE_AFFI {COUL, VUM}; // couleur, vu-metre
MODE_AFFI mode_affi = VUM;
//enum MODE_SELECT {FRQ, MEM};
#define _FRQ 0
#define _MEM 1
uint8_t mode_s;
enum BANDE {SW, FM, AIR};
BANDE bande_active = FM;
uint16_t FRQ_x0 = 50;
uint16_t FRQ_y0 = 30;
uint16_t x0_box_EEPROM = 0;
uint16_t y0_box_EEPROM = 135;
uint16_t x0_box_PRESET =2;
uint16_t y0_box_PRESET =87;
uint16_t x0_box_BANDE = 205; // SW - FM - AIR
uint16_t y0_box_BANDE = 115;
uint16_t x0_numPad = 70;
uint16_t y0_numPad = 117;
uint16_t x0_vu_metre = 170;
uint16_t y0_vu_metre = 145;
uint16_t x0_box_info = 70;
uint16_t y0_box_info = 218;
uint16_t x0_choix_couleur = 170;
uint16_t y0_choix_couleur= 145;
uint8_t n_appui = 0; // incrémenté à chaque appui sur une touche du numPad numérique
uint32_t total_saisi =0;
uint16_t x_touch, y_touch;
uint16_t status;
int16_t level;
uint16_t usn;
uint16_t wam;
int16_t offset;
uint16_t bandwidth;
uint16_t mod;
int8_t snr;
uint16_t A_block;
uint16_t B_block;
uint16_t C_block;
uint16_t D_block;
uint16_t dec_error;
float position_aiguille = 0; // vu-metre
uint16_t couleur_traits = GRIS_5;
uint16_t JAUNE_chiffres = 65504;
uint16_t VERT_chiffres = 2016;
uint8_t cR = 0;
uint8_t cG = 0;
uint8_t cB = 0;
uint16_t couleur_fond_ecran = 0;
float degTOrad(float angle)
{
return (angle * M_PI / 180.0);
}
uint8_t decToBcd( int val )
{
return (uint8_t) ((val / 10 * 16) + (val % 10));
}
uint16_t Color_To_565(uint8_t r, uint8_t g, uint8_t b)
{
return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3);
}
void RGB565_to_888(uint16_t color565, uint8_t *R, uint8_t *G, uint8_t *B)
{
*R=(color565 & 0xF800) >> 8;
*G=(color565 & 0x7E0) >> 3;
*B=(color565 & 0x1F) << 3 ;
}
/** ***********************************************************************************
CAPTURE D'ECRAN vers SDcard
**************************************************************************************
ATTENTION : cette fonction est simultanément incompatible avec la fonction tactile (TOUCHSCREEN) de l'afficheur
pour des raisons d'attribution des bus spi.(il n'y a que deux bus SPI personnalisés DISPONIBLES sur
les 4 de l'ESP32 (2 sont à usage interne),
il en manque donc un troisième !)
SCREEN SPI : (tel que défini dans le fichier User_Setup.h)
TFT_MISO GPIO 12 // don't define this pin when using Touch and SD Card on the CYD
TFT_MOSI GPIO 13
TFT_SCLK GPIO 14
TFT_CS GPIO 15 // Chip select control pin
TFT_DC GPIO 2 // Data Command control pin
TFT_RST GPIO 4 // Reset pin (could connect to RST pin)
TFT_RST -1 // Set TFT_RST to -1 if display RESET is connected to ESP32 board RST
TOUCHSCREEN SPI :
IRQ (XPT2046_IRQ) GPIO 36
MOSI (XPT2046_MOSI) GPIO 32
MISO (XPT2046_MISO) GPIO 39
CLK (XPT2046_CLK) GPIO 25
CS (XPT2046_CS) GPIO 33
MicoSD card SPI :
MISO GPIO 19
MOSI GPIO 23
SCK GPIO 18
CS GPIO 5
Il est possible de partager un même bus SPI entre plusieurs composants, (one master and multi slaves)
mais ce n'est pas ce qui a été fait par les concepteurs de la CYD.
Les deux bus internes sont utilisés, il n'en reste plus de disponible.
voir l'URL très simple(!) suivante :
https://medium.com/@androidcrypto/how-to-use-touch-and-sd-card-at-the-same-time-on-an-esp32-cheap-yellow-display-cyd-45fa55d01ffe
*/
void init_SDcard()
{
Serial.println("init_SDcard()");
if(!SD.begin())
{
Serial.println("Card Mount Failed");
delay (1000);
return;
}
uint8_t cardType = SD.cardType();
if(cardType == CARD_NONE)
{
Serial.println("No SDcard");
delay (1000);
return;
}
SDcardOk=1;
Serial.print("SDcard Type: ");
if(cardType == CARD_SD) { Serial.println("SDSC"); }
else if(cardType == CARD_SDHC) { Serial.println("SDHC"); }
uint32_t cardSize = SD.cardSize() / (1024 * 1024);
String s1=(String)cardSize + " GB";
Serial.print("SDcard size: ");
Serial.println(s1);
delay (1000);
Serial.println("FIN init_SDcard()");
}
// Fonction optimisée pour la carte CYD 320x240px avec la library 'TFT_eSPI'
// ne convient PAS pour les ESP32 Wroom + afficheur 3.5" TFT 480x320
void write_TFT_on_SDcard() // enregistre image bmp 320x240 RGB888
{
do_wr_ecran_on_sd =0;
if (SDcardOk==0) {return;}
int32_t x, y;
uint16_t color565;
uint8_t octet_A;
uint8_t octet_B;
if( ! SD.exists("/bmp/320x240_565.bmp")) {return;}
File File1 = SD.open("/bmp/320x240_565.bmp", FILE_WRITE); // ouverture du fichier binaire (vierge) en écriture
if (File1)
{
/*
Les images en couleurs réelles BMP888 utilisent 24 bits par pixel:
Il faut 3 octets pour coder chaque pixel, en respectant l'ordre de l'alternance bleu, vert et rouge.
*/
uint16_t bmp_offset = 138;
File1.seek(bmp_offset);
TFT.setFreeFont(FF0);
TFT.setTextSize(1);
TFT.setTextColor(JAUNE, NOIR);
for (y=240; y>0; y--)
{
for (x=0; x<320; x++)
{
color565=TFT.readPixel(x, y); // BBBBBrrr rrrVVVVV
octet_B = (color565 & 0b1111111100000000) >> 8;
octet_A = (color565 & 0b0000000011111111);
//octet_A =0b11111000; octet_B =0b00000000 // ok tout bleu
//octet_A =0b00000111; octet_B =0b11100000; // ok tout rouge
//octet_A =0b00000000; octet_B =0b00011111; // ok tout vert
File1.write(octet_A);
File1.write(octet_B);
}
String s1=String(y/10); TFT.drawString(s1, 170, 115); // affiche compte à rebour
}
File1.close(); // referme le fichier
TFT.fillRect(170, 115, 20, 8, GRIS_2); // efface le compte à rebour
}
}
// ***********************************************************************************************************
void affiche_index_frq() // 6 petits boutons juste au dessus de chaque chiffre pour indiquer celui à modifier
{
int x = FRQ_x0 +15;
int y = FRQ_y0 - 5;
uint16_t c1 = NOIR;
uint16_t c2 = VERT;
bt_1.init(x, y, 20, 5, 0); bt_1.affiche(c1, c2, 1); x+=31;
bt_2.init(x, y, 20, 5, 0); bt_2.affiche(c1, c2, 1); x+=31;
bt_3.init(x, y, 20, 5, 0); bt_3.affiche(c1, c2, 1); x+=46;
bt_4.init(x, y, 20, 5, 0); bt_4.affiche(c1, c2, 1); x+=31;
bt_5.init(x, y, 20, 5, 0); bt_5.affiche(c1, c2, 1); x+=31;
bt_6.init(x, y, 20, 5, 0); bt_6.affiche(c1, c2, 1);
}
void init_boutons_Plus_Moins()// boutons '+' et '-'
{
int x0 = 240;
int y0 = 90;
uint16_t c1 = GRIS_6;
uint16_t c2 = JAUNE;
bt_moins.init(x0, y0, 30, 20, 3);
bt_moins.cliked = false;
bt_moins.s="-";
bt_moins.affiche(c1, c2 ,3);
bt_plus.init(x0+35, y0, 30, 20, 3);
bt_plus.cliked = false;
bt_plus.s="+";
bt_plus.affiche(c1, c2 ,3);
}
// bt_SW
// bt_FM
// bt_AIR
void init_boutons_BANDE() // (SW - FM - AIR)
{
TFT.setFreeFont(FF0);
bt_SW.init(x0_box_BANDE+4, y0_box_BANDE+5, 30, 15, 3);
bt_SW.cliked = false;
bt_SW.selected = false;
bt_SW.s="SW";
bt_SW.affiche(GRIS_6, NOIR, 1);
bt_FM.init(x0_box_BANDE+37, y0_box_BANDE+5, 30, 15, 3);
bt_FM.cliked = false;
bt_FM.selected = false;
bt_FM.s="FM";
bt_FM.affiche(GRIS_6, NOIR, 1);
bt_AIR.init(x0_box_BANDE+70, y0_box_BANDE+5, 30, 15, 3);
bt_AIR.cliked = false;
bt_AIR.selected = false;
bt_AIR.s="AIR";
bt_AIR.affiche(GRIS_6, NOIR, 1);
}
void init_bouton_Mute()
{
int x0 = 5;
int y0 = 120;
bt_mute.init(x0, y0, 30, 15, 3);
bt_mute.selected = false;
bt_mute.cliked = false;
bt_mute.s="Mute";
bt_mute.affiche(NOIR, ROUGE, 1);
}
void init_bouton_Sleep()
{
int x0 = 5;
int y0 = 220;
bt_sleep.init(x0, y0, 40, 15, 3);
bt_sleep.selected = false;
bt_sleep.cliked = false;
bt_sleep.s="Sleep";
bt_sleep.affiche(NOIR, ROUGE, 1);
}
void init_bouton_test()
{
int x0 = 160;
int y0 = 120;
bt_test.init(x0, y0, 35, 15, 3);
bt_test.selected = false;
bt_test.cliked = false;
bt_test.s="test";
bt_test.affiche(GRIS_3, BLANC, 1);
}
void init_bt_affi_box_couleurs()
{
uint16_t c1 = NOIR;
uint16_t c2 = VERT;
bt_affi_box_couleurs.init(268, 223, 50, 15, 2);
bt_affi_box_couleurs.cliked = false;
bt_affi_box_couleurs.selected = false;
bt_affi_box_couleurs.s = "couleur";
bt_affi_box_couleurs.affiche(c1, c2, 1);
}
void init_bouton_EE_RAZ()
{
TFT.setFreeFont(FF0);
bt_EE_RAZ.init(x0_box_EEPROM+4, y0_box_EEPROM+20, 40, 15, 3);
bt_EE_RAZ.cliked = false;
bt_EE_RAZ.selected = false;
bt_EE_RAZ.s="Raz";
bt_EE_RAZ.affiche(GRIS_6, NOIR, 1);
}
void init_bouton_EE_write()
{
TFT.setFreeFont(FF0);
bt_EE_write.init(x0_box_EEPROM+4, y0_box_EEPROM+40, 40, 15, 3);
bt_EE_write.cliked = false;
bt_EE_write.selected = false;
bt_EE_write.s="Write";
bt_EE_write.affiche(GRIS_6, NOIR, 1);
}
void init_bouton_EE_read()
{
TFT.setFreeFont(FF0);
bt_EE_read.init(x0_box_EEPROM+4, y0_box_EEPROM+60, 40, 15, 3);
bt_EE_read.cliked = false;
bt_EE_read.selected = false;
bt_EE_read.s="Read";
bt_EE_read.affiche(GRIS_6, NOIR, 1);
}
void init_boutons_MODE()
{
uint16_t c1 = NOIR;
uint16_t c2 = VERT;
TFT.setFreeFont(FF0);
TFT.setTextColor(GRIS_3, NOIR);
TFT.drawString("mode", 6, 17);
TFT.drawFastVLine(45, 15, 72, couleur_traits);
bt_mode_FRQ.init(5, 35, 35, 20, 3);
bt_mode_FRQ.selected = true;
bt_mode_FRQ.s="FRQ";
bt_mode_FRQ.affiche(c1, c2, 1);
bt_mode_MEM.init(5, 60, 35, 20, 3);
bt_mode_MEM.selected = false;
bt_mode_MEM.s="MEM";
bt_mode_MEM.affiche(c1, c2, 1);
affiche_index_frq();
}
void init_1_bouton_preset(uint16_t xi, uint16_t yi, String si, TOUCH_BOUTON_PRESET *bouton_i)
{
uint16_t c1 = NOIR;
uint16_t c2 = BLANC;
if (mode_affi == COUL) {c1 = bouton_i->couleur;}
bouton_i->init(xi, yi, 15, 15, 3);
bouton_i->cliked = false;
bouton_i->selected = false;
bouton_i->s = si;
bouton_i->affiche(c1, c2, 1);
}
void init_boutons_presets()
{
uint16_t x = x0_box_PRESET +5;
uint16_t y = y0_box_PRESET +5;
init_1_bouton_preset(x, y, "1", &bt_station1); x+=20;
init_1_bouton_preset(x, y, "2", &bt_station2); x+=20;
init_1_bouton_preset(x, y, "3", &bt_station3); x+=20;
init_1_bouton_preset(x, y, "4", &bt_station4); x+=20;
init_1_bouton_preset(x, y, "5", &bt_station5); x+=20;
init_1_bouton_preset(x, y, "6", &bt_station6); x+=20;
init_1_bouton_preset(x, y, "7", &bt_station7); x+=20;
init_1_bouton_preset(x, y, "8", &bt_station8);
}
void affiche_1_bt_RGB(TOUCH_BOUTON *bouton_i, uint16_t x, uint16_t y, uint8_t dx, uint16_t couleur, String s_i)
{
uint16_t c1 = couleur;
uint16_t c2 = JAUNE;
bouton_i->init(x, y, dx, 14, 3);
bouton_i->cliked = false;
bouton_i->selected = false;
bouton_i->s = s_i;
bouton_i->affiche(c1, c2, 1);
}
void affiche_box_choix_couleur()
{
uint16_t x0 = x0_choix_couleur;
uint16_t y0 = y0_choix_couleur;
uint16_t x, y;
uint16_t c1 = GRIS_5;
uint16_t c2 = JAUNE;
TFT.setFreeFont(FF0);
TFT.setTextColor(BLANC), NOIR;
TFT.drawRect(x0-1, y0-1, 142, 72, NOIR); // contour, visible sur fonds très clairs...
TFT.fillRect(x0, y0, 140, 70, GRIS_2);
x = x0+15;
y = y0+2;
TFT.drawString("R", x-10, y+5);
affiche_1_bt_RGB(&bt_R_moins, x, y, 18, GRIS_5, "-");
x+=20;
affiche_1_bt_RGB(&bt_R_plus, x, y, 18, GRIS_5, "+");
x=x0+15; y+=18;
TFT.drawString("G", x-10, y+5);
affiche_1_bt_RGB(&bt_G_moins, x, y, 18, GRIS_5, "-");
x+=20;
affiche_1_bt_RGB(&bt_G_plus, x, y, 18, GRIS_5, "+");
x=x0+15; y+=18;
TFT.drawString("B", x-10, y+5);
affiche_1_bt_RGB(&bt_B_moins, x, y, 18, GRIS_5, "-");
x+=20;
affiche_1_bt_RGB(&bt_B_plus, x, y, 18, GRIS_5, "+");
x=x0+122; y=y0;
affiche_1_bt_RGB(&bt_close1, x, y, 18, GRIS_5, "x");
x=x0+5; y=y0+55;
affiche_1_bt_RGB(&bt_coul_to_EEPROM, x, y, 60, ROUGE, "W EEPROM");
x=x0+100; y=y0+55;
affiche_1_bt_RGB(&bt_RST_affi, x, y, 18, GRIS_5, "ok");
TFT.fillRoundRect(x0+80, y0+10, 40, 40, 5, couleur_fond_ecran);
RGB565_to_888(couleur_fond_ecran, &cR, &cG, &cB);
affi_valeurs_RGB();
}
void init_sprites()
{
sprite_frq.createSprite(220, 55);
sprite_frq.loadFont(digitfont1);
sprite_frq.setTextColor(JAUNE_2, NOIR);
sprite_frq.setTextDatum(MR_DATUM); // alignement du texte
}
void Tuner_Reset(void)
{
Wire.beginTransmission(0x64);
Wire.write(0x1e);
Wire.write(0x5a);
Wire.write(0x01);
Wire.write(0x5a);
Wire.write(0x5a);
Wire.endTransmission();
}
bool Tuner_Table_Write(const unsigned char *tab)
{
if (tab[1] == 0xff)
{
delay(tab[2]);
return 1;
}
else { return Tuner_WriteBuffer((unsigned char *)&tab[1], tab[0]); }
}
void Tuner_Init(const unsigned char *table)
{
uint16_t r;
const unsigned char *p = table;
for (uint16_t i = 0; i < sizeof(tuner_init_tab9216); i += (pgm_read_byte(p + i) + 1))
{
if (1 != (r = Tuner_Table_Write(p + i))) break;
}
}
void boutons_preset_set_frequences()
{
if(bande_active == FM)
{
bt_station1.frequence = 89400; bt_station1.nom = "Inter";
bt_station2.frequence = 92900; bt_station2.nom = "Musique";
bt_station3.frequence = 95600; bt_station3.nom = "RFM";
bt_station4.frequence = 97800; bt_station4.nom = "Culture";
bt_station5.frequence = 101100; bt_station5.nom = "Herault";
bt_station6.frequence = 90600; bt_station6.nom = "RTL";
bt_station7.frequence = 90100; bt_station7.nom = "FUN Radio";
bt_station8.frequence = 107300; bt_station8.nom = "R Classique";
}
if(bande_active == SW)
{
bt_station1.frequence = 9590; bt_station1.nom = "SW1";
bt_station2.frequence = 11600; bt_station2.nom = "SW2";
bt_station3.frequence = 13640; bt_station3.nom = "SW3";
bt_station4.frequence = 17790; bt_station4.nom = "SW4";
bt_station5.frequence = 8000; bt_station5.nom = "SW5";
bt_station6.frequence = 12000; bt_station6.nom = "SW6";
bt_station7.frequence = 18000; bt_station7.nom = "SW7";
bt_station8.frequence = 24000; bt_station8.nom = "SW8";
}
if(bande_active == AIR)
{
bt_station1.frequence = 131050; bt_station1.nom = "air1";
bt_station2.frequence = 120925; bt_station2.nom = "air2";
bt_station3.frequence = 124075; bt_station3.nom = "air3";
bt_station4.frequence = 125000; bt_station4.nom = "air4";
bt_station5.frequence = 124000; bt_station5.nom = "air5";
bt_station6.frequence = 125000; bt_station6.nom = "air6";
bt_station7.frequence = 126000; bt_station7.nom = "air7";
bt_station8.frequence = 127000; bt_station8.nom = "air8";
}
bt_station1.couleur = 10240; // rouge sombre
bt_station2.couleur = 14528; // orange
bt_station3.couleur = 320; // vert
bt_station4.couleur = 14407; //violet
bt_station5.couleur = 26787; // rose
bt_station6.couleur = 260; //cyan
bt_station7.couleur = 267; //bleu ciel
bt_station8.couleur = 4; // bleu marine
}
void Tune_Frequence(uint32_t F)
{
TFT.setFreeFont(FF0);
TFT.setTextColor(BLEU, NOIR);
String s1 = String(F);
TFT.drawString(s1, 80, 4);
if (F == 1500)
{
//Tune_Frequence_AM(F);
TFT.fillRect(130, 1, 100, 12, NOIR); // efface
TFT.setTextColor(ROUGE, NOIR);
TFT.drawString("MINIMUM ", 130, 4);
}
if (bande_SW)
{
Tune_Frequence_AM(F);
TFT.fillRect(130, 1, 100, 12, NOIR); // efface
TFT.setTextColor(VERT, NOIR);
TFT.drawString("SW ", 130, 4);
}
if (bande_interdite1)
{
//Tune_Frequence_AM(F);
TFT.fillRect(130, 1, 100, 12, NOIR); // efface
TFT.setTextColor(ROUGE, NOIR);
TFT.drawString("NON DISPONIBLE", 130, 4);
bt_SW.selected = false;
bt_FM.selected = false;
bt_AIR.selected = false;
}
if (bande_FM)
{
Tune_Frequence_FM(F/10);
TFT.fillRect(130, 1, 100, 12, NOIR); // efface
TFT.setTextColor(VERT, NOIR);
TFT.drawString("bande FM", 130, 4);
}
if (bande_interdite2)
{
//Tune_Frequence_AM(F);
TFT.fillRect(130, 1, 100, 12, NOIR); // efface
TFT.setTextColor(ROUGE, NOIR);
TFT.drawString("NON DISPONIBLE", 130, 4);
bt_SW.selected = false;
bt_FM.selected = false;
bt_AIR.selected = false;
}
if (bande_AIR)
{
Tune_Frequence_AM(F-110000); // nécessite un convertisseur de fréquence 110MHz en entrée antenne
TFT.fillRect(130, 1, 100, 12, NOIR); // efface
TFT.setTextColor(BLEU_CLAIR, NOIR);
TFT.drawString("AIR BAND", 130, 4);
}
if (F == 138000)
{
TFT.fillRect(130, 1, 40, 12, NOIR); // efface
TFT.setTextColor(ROUGE, NOIR);
TFT.drawString("F MAX ", 130, 4);
}
}
void load_GRP_FREQ_EEPROM()
{
Serial.println("--- Frequences lues en EEPROM ---------------");
Serial.println(" ");
Serial.println("GROUPE SW");
groupe_SW.load_bloc(); // EEPROM -> RAM
groupe_SW.tri_bloc(); // en RAM
groupe_SW.bloc_to_serial();
Serial.println("---------------------------------------------");
Serial.println("GROUPE FM");
groupe_FM.load_bloc(); // EEPROM -> RAM
groupe_FM.tri_bloc(); // en RAM
groupe_FM.bloc_to_serial();
Serial.println("---------------------------------------------");
Serial.println("GROUPE AIR");
groupe_AIR.load_bloc(); // EEPROM -> RAM
groupe_AIR.tri_bloc(); // en RAM
groupe_AIR.bloc_to_serial();
Serial.println("---------------------------------------------");
}
uint16_t brightness(uint16_t couleur)
{
uint8_t r, g, b;
r = 0xFF & (couleur >> 16);
g = 0xFF & (couleur >> 8);
b = 0xFF & couleur;
return ( r + g + b );
}
void init_affichages()
{
TFT.fillScreen(couleur_fond_ecran); // couleur de fond d'écran
if (brightness(couleur_fond_ecran) > 500) {couleur_traits = NOIR;} else {couleur_traits = BLANC;}
TFT.setTextColor(JAUNE, NOIR);
TFT.drawRect(0, 0, 319, 240, couleur_traits); // cadre principal pourtour de l'écran
init_sprites();
while (!Serial && (millis() <= 1000));
init_boutons_MODE();
init_bouton_EE_RAZ();
init_bouton_EE_write();
TFT.setFreeFont(FF0);
init_boutons_Plus_Moins();
init_boutons_BANDE(); // (SW - FM - AIR)
init_bouton_Mute();
init_bouton_Sleep();
init_bouton_test();
init_bouton_EE_write();
init_bouton_EE_read();
numPad1.init(x0_numPad, y0_numPad, true);
affiche_box_entete();
init_box_info();
affiche_box_FRQ(GRIS_3);
affiche_box_presets();
affiche_box_BANDE();
affiche_box_EEPROM();
init_boutons_presets();
uint16_t c1 = NOIR;
uint16_t c2 = GRIS_2;
bt_4.selected = true;
bt_4.cliked = true;
bt_4.affiche(c1, c2,1);
bt_mute.selected = false;
bt_mute.cliked = false;
bt_mute.affiche(NOIR, ROUGE, 1);
affiche_frequence(frequence);
if(mode_affi == VUM)
{
dessine_VuMetre();
init_bt_affi_box_couleurs();
}
if(mode_affi == COUL)
{
affiche_box_choix_couleur();
}
}
void setup()
{
Serial.begin(115200);
#ifdef _SD_CARD
init_SDcard(); // attention : incompatible avec le TOUCHPAD
#endif
Wire.begin(GPIO_SDA, GPIO_SCL, 100000);
Serial.println("display.init()");
#ifndef _SD_CARD
// Start the SPI for the touch screen and init the TS library
// attention : incompatible avec SD_card
mySpi.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS);
ts.begin(mySpi);
ts.setRotation(3);
#endif
TFT.init();
TFT.setRotation(3); // 0..3 à voir, suivant disposition de l'afficheur et sa disposition
TFT.fillScreen(NOIR);
TFT.setTextColor(BLANC, NOIR);
TFT.setFreeFont(FF1);
uint16_t y=0;
Serial.println("Radio TEF6686");
TFT.drawString("Radio TEF6686", 0, y); y+=20;
String s1="version " + version;
TFT.drawString(s1, 0, y); y+=20;
TFT.drawString("Silicium628", 0, y); y+=40;
TFT.setFreeFont(FF0);
TFT.drawString("SW (AM) 1500kHz -- 28MHz", 0, y); y+=20;
TFT.drawString("bande FM (WFM) 88MHz -- 108MHz", 0, y); y+=20;
TFT.drawString("Civil Air band(AM) 118MHz -- 137MHz", 0, y); y+=20;
delay(1000);
// adresses physiques des blocs en EEPROM:
groupe_SW.adr_0 = 100; // je réserve les 100 premiers octets (0..99) pour des paramètres divers
groupe_FM.adr_0 = groupe_SW.adr_0 + 400; // donc =500 (chaque fréquence occupe 4 octets (uint_32t))
groupe_AIR.adr_0 = groupe_FM.adr_0 + 400; // donc =900
boutons_preset_set_frequences();
EEPROM.begin(EEPROM_SIZE);
couleur_fond_ecran = EEPROM.readShort(0); // 2 octets = 16 bits
frequence = EEPROM.readUInt(EEPROM_adrs_freq); // 4 octets = 32 bits
Serial.print("mode_s LU en EEPROM: "); Serial.println(mode_s);
init_affichages();
Serial.print("mode_s ici2: "); Serial.println(mode_s);
Serial.println("---------------------------------------------");
saut_freq = 100;
Tuner_Init(tuner_init_tab9216);
Serial.println(" ");
/*
The TEF668X consists of four modules:
-module 32 : FM = FM radio reception
-module 33 : AM = LW, MW and SW radio reception
-module 48 : AUDIO = Audio processing
-module 64 : APPL = System and application control
*/
load_GRP_FREQ_EEPROM();
Set_no_AM_gain_reduction();
mode_s = EEPROM.readByte(EEPROM_adrs_mode); // 1 octet
if(mode_s == _FRQ) {bt_mode_FRQ.selected = true; bt_mode_MEM.selected = false;}
if(mode_s == _MEM) {bt_mode_FRQ.selected = false; bt_mode_MEM.selected = true;}
uint16_t c1 = GRIS_6;
uint16_t c2 = VERT;
uint16_t c3 = JAUNE;
bt_mode_FRQ.affiche(c1, c2, 1);
bt_mode_MEM.affiche(c1, c3, 1);
uint32_t Frq = EEPROM.readUInt(EEPROM_adrs_freq); // 4 octets = 32 bits
if (Frq != 0)
{
deselect_boutons_presets();
frequence = Frq;
}
else
{
frequence = bt_station4.frequence;
clic_logiciel_bouton(&bt_station4);
}
affiche_frequence(frequence);
Tune_Frequence(frequence);
Set_Volume(+60);
Serial.print("mode_s ici3: "); Serial.println(mode_s);
Serial.print("------------- FIN DU SETUP -----------------");
delay(100);
// FIN DU SETUP
}
void printTouchToDisplay(TS_Point p)
{
// Clear screen first
//TFT.fillScreen(TFT_BLACK);
//TFT.setTextColor(TFT_WHITE, TFT_BLACK);
int x = 320 / 2; // center of display
int y = 100;
int fontSize = 2;
//String temp = "P= " + String(p.z);
//TFT.drawCentreString(temp, x, y, fontSize);
x_touch = -30 + p.x /11;
y_touch = -30 + p.y /14;
// TFT.drawRect(x_touch, y_touch, 2, 2, JAUNE;
}
float ltx = 0; // Saved x coord of bottom of aiguille
uint16_t osx = x0_vu_metre;
uint16_t osy = y0_vu_metre;
// -------------------------------------------------------------------------
void dessine_VuMetre()
{
uint16_t x0 = x0_vu_metre;
uint16_t y0 = y0_vu_metre;
uint16_t dx=140;
uint16_t dy=70;
uint8_t AA = 65; // 65
uint8_t BB = x0 +dx/2;// 120
uint8_t CC = y0 + dy+20; // 140
TFT.setFreeFont(FF0);
// cadre rectangulaire
TFT.fillRect(x0, y0, dx, dy, GRIS_3);
TFT.fillRect(x0+3, y0+3, dx-6, dy-6, BLANC);
TFT.setTextColor(NOIR);
// graduation chaque 5 deg entre -50 et +50 deg
for (int i = -50; i < 51; i += 10)
{
int tl = 5; // tiret plus long
// Coordonnées du tiret à dessiner
float sx = cos((i - 90) * deg_to_rad);
float sy = sin((i - 90) * deg_to_rad);
uint16_t tx0 = sx * (AA + tl) + BB;
uint16_t ty0 = sy * (AA + tl) + CC;
uint16_t tx1 = sx * AA + BB;
uint16_t ty1 = sy * AA + CC;
// Coordonnées of next tick for zone fill
float sx2 = cos((i + 5 - 90) * deg_to_rad);
float sy2 = sin((i + 5 - 90) * deg_to_rad);
int tx2 = sx2 * (AA + tl) + BB;
int ty2 = sy2 * (AA + tl) + CC;
int tx3 = sx2 * AA + BB;
int ty3 = sy2 * AA + CC;
// zone verte
if (i >= 0 && i < 25)
{
TFT.fillTriangle(tx0, ty0, tx1, ty1, tx2, ty2, VERT);
TFT.fillTriangle(tx1, ty1, tx2, ty2, tx3, ty3, VERT);
}
// zone orange
if (i >= 25 && i < 50)
{
TFT.fillTriangle(tx0, ty0, tx1, ty1, tx2, ty2, ORANGE);
TFT.fillTriangle(tx1, ty1, tx2, ty2, tx3, ty3, ORANGE);
}
if (i % 25 != 0) tl = 8; // Short scale tick length
// Recalcule coords in case tick lenght changed
tx0 = sx * (AA + tl) + BB;
ty0 = sy * (AA + tl) + CC;
tx1 = sx * AA + BB;
ty1 = sy * AA + CC;
// Draw tick
TFT.drawLine(tx0, ty0, tx1, ty1, NOIR);
// Check if labels should be drawn, with position tweaks
if (i % 20 == 0)
{
// Calculate label positions
tx0 = sx * (AA + tl + 10) + BB;
ty0 = sy * (AA + tl + 10) + CC;
switch (i / 20)
{
case -2: TFT.drawCentreString("0", tx0, ty0 - 6, 1); break;
case -1: TFT.drawCentreString("25", tx0, ty0 - 4, 1); break;
case 0: TFT.drawCentreString("50", tx0, ty0 - 6, 1); break;
case 1: TFT.drawCentreString("75", tx0, ty0 - 4, 1); break;
case 2: TFT.drawCentreString("100", tx0, ty0 - 6, 1); break;
}
}
// draw the arc of the scale
sx = cos((i + 5 - 90) * deg_to_rad);
sy = sin((i + 5 - 90) * deg_to_rad);
tx0 = sx * AA + BB;
ty0 = sy * AA + CC;
// Draw scale arc, don't draw the last part
if (i < 50) {TFT.drawLine(tx0, ty0, tx1, ty1, NOIR);}
}
//TFT.drawRect(x0, y0+dy-20, dx, 20, NOIR);
}
void plotAiguille(float value)
{
uint16_t x0 = x0_vu_metre;
uint16_t y0 = y0_vu_metre;
uint16_t dx=140;
uint16_t dy=50;
uint8_t AA = dx/2; // 100
uint8_t BB = x0 +dx/2;// 120
uint8_t CC = y0 + dy+25; // 140
TFT.setTextColor(TFT_BLACK, BLANC);
char buf[8]; dtostrf(value, 4, 0, buf);
if (value < -10) value = -10; // Limit value to emulate aiguille end stops
if (value > 110) value = 110;
float sdeg = map(value, -10, 110, -150, -30); // Map value to angle
// Calcul aiguille coords
float sx = cos(sdeg * deg_to_rad);
float sy = sin(sdeg * deg_to_rad);
// Calcul x delta of aiguille start (does not start at pivot point)
float tx = tan((sdeg + 90) * deg_to_rad);
// Erase old aiguille image
TFT.drawLine(BB + 20 * ltx - 1, CC - 20, osx - 1, osy, BLANC);
TFT.drawLine(BB + 20 * ltx, CC - 20, osx, osy, BLANC);
TFT.drawLine(BB + 20 * ltx + 1, CC - 20, osx + 1, osy, BLANC);
// Store new aiguille end coords for next erase
ltx = tx;
osx = sx * 50 + BB;
osy = sy * 50 + CC;
// Draw aiguille in the new postion
// draws 3 lines to thicken aiguille
TFT.drawLine(BB + 20 * ltx - 1, CC - 20, osx - 1, osy, ROUGE);
TFT.drawLine(BB + 20 * ltx, CC - 20, osx, osy, VIOLET);
TFT.drawLine(BB + 20 * ltx + 1, CC - 20, osx + 1, osy, ROUGE);
TFT.fillRect(x0, y0+dy+5, dx, 15, GRIS_2);
}
void init_box_info()
{
TFT.drawRect(x0_box_info, y0_box_info, 180, 16, NOIR);
TFT.setFreeFont(FF0);
TFT.setTextColor(JAUNE, couleur_fond_ecran);
TFT.drawString("RDS", x0_box_info -20, y0_box_info + 4);
}
void affiche_unit(String s)
{
TFT.setTextColor(JAUNE, NOIR);
TFT.setFreeFont(FM9); //FM9 FMB9 FSS9... voir le fichier Free_Fonts.h
TFT.drawString(s, FRQ_x0 + 225, FRQ_y0 + 35);
}
void efface_numero_frq()
{
TFT.fillRect(FRQ_x0 + 225, FRQ_y0 + 20, 40, 12, couleur_fond_ecran);
}
void affiche_numero_frq(String s1, String s2)
{
//TFT.fillRect(FRQ_x0 + 225, FRQ_y0 + 5, 10, 10, BLEU);
TFT.setTextColor(BLANC, couleur_fond_ecran);
TFT.setFreeFont(FF0);
TFT.drawString(s1 + "/" + s2 + " ", FRQ_x0 + 225, FRQ_y0 + 20);
affiche_box_FRQ(GRIS_3); // pour retracer le côté droit du rectangle
}
void affiche_band(String s)
{
//TFT.fillRect(FRQ_x0 + 225, FRQ_y0 + 5, 10, 10, BLEU);
TFT.setTextColor(BLANC, NOIR);
TFT.setFreeFont(FM9);
String blancs;
if (s == "AIR") {blancs = " ";} else {blancs = " ";}
TFT.drawString(s + blancs, FRQ_x0 + 225, FRQ_y0);
affiche_box_FRQ(GRIS_3); // pour retracer le côté droit du rectangle
}
void affiche_box_entete()
{
TFT.fillRect(0, 0, 320, 14, NOIR);
}
void affiche_box_FRQ(uint16_t couleur) // autour de la fréquence (en gros chiffres JAUNE
{
TFT.drawRect(0, FRQ_y0 -17, 319, 74, couleur);
}
void affiche_box_presets() // boutons 1 2 3 4 5 6 7 8
{
TFT.fillRect(x0_box_PRESET, y0_box_PRESET, 164, 24, NOIR);
TFT.setTextColor(GRIS_3, NOIR);
//TFT.drawString("presets", 5, 90);
}
void affiche_box_BANDE() // les 3 boutons SW, FM, AIR
{
TFT.drawRect(x0_box_BANDE, y0_box_BANDE, 105, 25, couleur_traits);
TFT.setFreeFont(FF0);
}
void affiche_box_EEPROM() // RAZ, WRITE, READ ...
{
TFT.drawRect(x0_box_EEPROM, y0_box_EEPROM + 10, 50, 70, couleur_traits);
TFT.setFreeFont(FF0);
TFT.setTextColor(GRIS_3, NOIR);
TFT.drawString("EEPROM", x0_box_EEPROM+6, y0_box_EEPROM+6);
}
void affiche_frequence(uint32_t frq) // en kHz, sans décimales
{
uint16_t c1 = NOIR;
uint16_t c2 = VERT;
uint16_t couleur_chiffres;
if(mode_s == _FRQ) {couleur_chiffres = VERT_chiffres;}
if(mode_s == _MEM) {couleur_chiffres = JAUNE_chiffres;}
if(bande_SW) // SW - 28 MHz = limite haute du module
{
affiche_band("SW");
bande_active = SW;
boutons_preset_set_frequences();
bt_SW.selected = true;
bt_FM.selected = false; // les boutons sont exclusifs
bt_AIR.selected = false;
bt_SW.affiche(c1, c2, 1); bt_FM.affiche(c1, c2, 1); bt_AIR.affiche(c1, c2, 1);
String s1, sM, sK;
uint8_t L;
s1 = String(frq);
s1 = "000000" + s1;
L= s1.length();
sK = s1.substring(L-3); // kHz
sM = s1.substring(L-6, L-3); // Mhz
sprite_frq.fillRect(0,0,220, 60, NOIR); // efface
sprite_frq.setTextColor(couleur_chiffres, NOIR);
sprite_frq.drawString(sM + "." + sK + " ", 220+10, 32);
// remarque: le fait d'ajouter " " à la fin évite aux chiffres de se balader horizontalement !
sprite_frq.pushSprite(FRQ_x0, FRQ_y0);
affiche_unit("MHz");
Tune_Frequence(frq);
}
if(bande_FM) // bande FM, on efface les deux '0' de droite
{
affiche_band("FM");
bande_active = FM;
boutons_preset_set_frequences();
bt_FM.selected = true;
bt_SW.selected = false; // les boutons sont exclusifs
bt_AIR.selected = false;
bt_SW.affiche(c1, c2, 1); bt_FM.affiche(c1, c2, 1); bt_AIR.affiche(c1, c2, 1);
String s1, sM, sK;
uint8_t L;
s1 = String(frq);
s1 = "000000" + s1;
L= s1.length();
sK = s1.substring(L-3, L-2); // kHz
if (frq < 100000) {sM = s1.substring(L-5, L-3); }// on ne retient que deux chiffres à gauche du point
else { sM = s1.substring(L-6, L-3); } // on garde 3 chiffres à gauche du point décimal
sprite_frq.fillRect(0,0,220, 60, NOIR); // efface
sprite_frq.setTextColor(couleur_chiffres, NOIR);
sprite_frq.drawString(sM + "." + sK + " ", 220-50, 32);
// remarque: le fait d'ajouter " " à la fin évite aux chiffres de se balader horizontalement !
sprite_frq.pushSprite(FRQ_x0, FRQ_y0);
affiche_unit("MHz");
Tune_Frequence(frq);
bt_mute.selected = false;
bt_mute.cliked = false;
bt_mute.affiche(NOIR, ROUGE, 1);
}
if(bande_AIR) // bande AIR - 138000-110000 = 28MHz (limite haute de réception AM du module)
{
affiche_band("AIR");
bande_active = AIR;
boutons_preset_set_frequences();
bt_AIR.selected = true;
bt_SW.selected = false; // les boutons sont exclusifs
bt_FM.selected = false;
bt_SW.affiche(c1, c2, 1); bt_FM.affiche(c1, c2, 1); bt_AIR.affiche(c1, c2, 1);
String s1, sM, sK;
uint8_t L;
s1 = String(frq);
s1 = "000000" + s1;
L= s1.length();
sK = s1.substring(L-3); // kHz
sM = s1.substring(L-6, L-3); // Mhz
sprite_frq.fillRect(0,0,220, 60, NOIR); // efface
sprite_frq.setTextColor(couleur_chiffres, NOIR);
sprite_frq.drawString(sM + "." + sK + " ", 220+10, 32);
// remarque: le fait d'ajouter " " à la fin évite aux chiffres de se balader horizontalement !
sprite_frq.pushSprite(FRQ_x0, FRQ_y0);
affiche_unit("MHz");
Tune_Frequence(frq);
}
if(bande_interdite1 || bande_interdite2) // bandes interdites par le module TEF6686
{
affiche_band("---");
String s1, sM, sK;
uint8_t L;
s1 = String(frq);
s1 = "000000" + s1;
L= s1.length();
sK = s1.substring(L-3); // kHz
sM = s1.substring(L-6, L-3); // Mhz
sprite_frq.fillRect(0,0,220, 60, NOIR); // efface
sprite_frq.setTextColor(couleur_chiffres, NOIR);
sprite_frq.drawString(sM + "." + sK + " ", 220+10, 32);
// remarque: le fait d'ajouter " " à la fin évite aux chiffres de se balader horizontalement !
sprite_frq.pushSprite(FRQ_x0, FRQ_y0);
affiche_unit("MHz");
//Tune_Frequence(frq);
}
if(frq==138000) { affiche_band("max"); }
if(frq>138000) { affiche_band("---"); }
}
void clic_logiciel_bouton(TOUCH_BOUTON *bouton_i)
{
uint16_t c1 = NOIR;
uint16_t c2 = BLEU;
bouton_i->cliked = true;
bouton_i->selected = true;
bouton_i->affiche(c1, c2, 1);
}
void test_clic_boutons(TOUCH_BOUTON *bouton_i)
{
uint16_t c1 = NOIR;
uint16_t c2 = GRIS_2;
if ((x_touch > bouton_i->x0) && (x_touch < bouton_i->x0 + bouton_i->dx)
&& ( y_touch > bouton_i->y0-5) && (y_touch < bouton_i->y0 + bouton_i->dy +5) )
{
bouton_i->cliked = true;
bouton_i->selected = true;
bouton_i->affiche(c1, c2, 1);
}
}
void test_clic_6_boutons_frq() //rectangles situés au dessus des gros chiffres de la fréquence
{
uint16_t c1 = NOIR;
uint16_t c2 = VERT;
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
{
bt_1.cliked = false; bt_1.selected = false; test_clic_boutons(&bt_1 ); bt_1.affiche(c1, c2,1);
bt_2.cliked = false; bt_2.selected = false; test_clic_boutons(&bt_2 ); bt_2.affiche(c1, c2,1);
bt_3.cliked = false; bt_3.selected = false; test_clic_boutons(&bt_3 ); bt_3.affiche(c1, c2,1);
bt_4.cliked = false; bt_4.selected = false; test_clic_boutons(&bt_4 ); bt_4.affiche(c1, c2,1);
bt_5.cliked = false; bt_5.selected = false; test_clic_boutons(&bt_5 ); bt_5.affiche(c1, c2,1);
bt_6.cliked = false; bt_6.selected = false; test_clic_boutons(&bt_6 ); bt_6.affiche(c1, c2,1);
if (bt_6.cliked) {saut_freq = 1;}
if (bt_5.cliked) {saut_freq = 10;}
if (bt_4.cliked) {saut_freq = 100;}
if (bt_3.cliked) {saut_freq = 1000;}
if (bt_2.cliked) {saut_freq = 10000;}
if (bt_1.cliked) {saut_freq = 100000;}
}
}
void traite_touches_pad(uint8_t num_touche)
{
if(num_touche == 253) {return;}
uint16_t c1 = GRIS_6;
uint16_t c2 = JAUNE;
uint16_t c3 = VERT;
int p1;
if (num_touche == 254) // bouton "."
{
frequence_txt += ".";
TFT.drawString(frequence_txt + " ", 250, 0);
}
if (num_touche < 10)
{
TFT.fillRect(250, 1, 60, 12, NOIR); // efface
frequence_txt += String(num_touche);
TFT.drawString(frequence_txt + " ", 250, 0);
delay(300);
}
x_touch =0;
y_touch =0;
if (num_touche == 255) // bouton "ok"
{
mode_s = _FRQ;
bt_mode_MEM.selected = false;
bt_mode_FRQ.selected = true;
bt_mode_MEM.affiche(c1, c2, 1);
bt_mode_FRQ.affiche(c1, c3, 1);
double F;
F = frequence_txt.toDouble();
p1 = frequence_txt.indexOf(".");
if (p1 != -1) {F *=1000;} // si présence du point décimal
frequence = F;
affiche_frequence(frequence); // 'Tune_Frequence(frq)' est appelée dans cette fonction 'affiche_frequence()'
n_appui = 0;
frequence_txt = "";
TFT.fillRect(250, 1, 60, 12, NOIR); // efface
n_appui = 0;
}
num_touche = 0;
}
uint32_t inc_Frq_in_groupe(GROUPE_FREQUENCES *groupe_Freq, int8_t di) // di = +/-1
{
if ((di<-1)||(di>1)) {return 0;}
uint16_t n_max = groupe_Freq->nb_freq;
uint16_t n = groupe_Freq->num_F_actuelle;
if (di == 1)
{
if (n<n_max-1) { n++; }
else if (n == (n_max-1)) {n=0;}
}
if (di == -1)
{
if (n>=1) { n--; }
else if (n==0) {n = n_max-1;}
}
groupe_Freq->num_F_actuelle = n;
uint16_t adr = groupe_Freq->adr_1ere_frq + n;
uint8_t nb_F = groupe_Freq->nb_freq;
uint8_t num_1ere_F = groupe_Freq->adr_1ere_frq;
affiche_numero_frq(String(1 + adr - num_1ere_F), String(nb_F));
uint32_t valeur_lue = groupe_Freq->G_freq[adr];
return valeur_lue;
}
void test_clic_boutons_plus_moins()
{
uint16_t c1 = GRIS_6;
uint16_t c2 = GRIS_3;
boolean bouton_cliked = false;
//uint16_t n=0;
affiche_box_entete(); // efface
//---------------------------------------------------------------------------------
if(mode_s == _FRQ) // on va modifier directement la fréquence
{
test_clic_boutons(&bt_plus ); bt_plus.affiche(c1, c2, 1);
if (bt_plus.cliked)
{
frequence += saut_freq;
bouton_cliked = true;
}
delay(20);
if (bt_plus.cliked && ((frequence + saut_freq) <= 138000 ))
{
Tune_Frequence(frequence);
}
bt_plus.cliked = false;
bt_plus.selected = false;
bt_plus.affiche(c1, c2, 1); // fugitif
test_clic_boutons(&bt_moins ); bt_moins.affiche(c1, c2, 2);
delay(20);
if (bt_moins.cliked)
{
if (frequence > saut_freq) // évite de se retrouver avec une F négative !
{
bouton_cliked = true;
frequence -= saut_freq;
}
}
if(bt_moins.cliked && frequence > saut_freq) { Tune_Frequence(frequence); }
bt_moins.cliked = false;
bt_moins.selected = false;
bt_moins.affiche(c1, c2, 2); // fugitif
if(bouton_cliked == true)
{
bouton_cliked = false;
affiche_frequence(frequence);
}
}
//---------------------------------------------------------------------------------
if(mode_s == _MEM) // on va parcourir les fréquences de la liste
{
test_clic_boutons(&bt_plus ); bt_plus.affiche(c1, c2, 1);
if (bt_plus.cliked)
{
bouton_cliked = true;
if(bande_active == SW) { frequence = inc_Frq_in_groupe(&groupe_SW, 1); }
if(bande_active == FM) { frequence = inc_Frq_in_groupe(&groupe_FM, 1); }
if(bande_active == AIR) { frequence = inc_Frq_in_groupe(&groupe_AIR, 1); }
Tune_Frequence(frequence);
delay(100);
}
bt_plus.cliked = false;
bt_plus.selected = false;
bt_plus.affiche(c1, c2, 1); // fugitif
test_clic_boutons(&bt_moins ); bt_moins.affiche(c1, c2, 2);
delay(20);
if (bt_moins.cliked)
{
bouton_cliked = true;
if(bande_active == SW) { frequence = inc_Frq_in_groupe(&groupe_SW, -1); }
if(bande_active == FM) { frequence = inc_Frq_in_groupe(&groupe_FM, -1); }
if(bande_active == AIR) { frequence = inc_Frq_in_groupe(&groupe_AIR, -1); }
Tune_Frequence(frequence);
delay(100);
}
bt_moins.cliked = false;
bt_moins.selected = false;
bt_moins.affiche(c1, c2, 2); // fugitif
if(bouton_cliked == true)
{
bouton_cliked = false;
affiche_frequence(frequence);
}
}
}
void test_clic_bt_RST_affi() // bouton "ok" de la box saisie couleur de fond ecran
{
if(mode_affi != COUL) {return;}
uint16_t c1 = GRIS_6;
uint16_t c2 = JAUNE;
test_clic_boutons(&bt_RST_affi );
//bt_sleep.affiche(NOIR, ROUGE, 1);
//delay(100);
if (bt_RST_affi.cliked)
{
bt_RST_affi.cliked = false;
bt_RST_affi.selected = true;
bt_RST_affi.affiche(NOIR, VERT, 1);
init_affichages();
}
}
void test_clic_bt_affi_box_couleurs() // bouton au coin en bas à droite
{
uint16_t c1 = GRIS_6;
uint16_t c2 = JAUNE;
test_clic_boutons(&bt_affi_box_couleurs );
//bt_sleep.affiche(NOIR, ROUGE, 1);
//delay(100);
if (bt_affi_box_couleurs.cliked)
{
bt_affi_box_couleurs.cliked = false;
bt_affi_box_couleurs.selected = true;
bt_affi_box_couleurs.affiche(NOIR, VERT, 1);
mode_affi = COUL;
init_affichages();
}
}
void test_clic_bt_coul_to_EEPROM() // enregistre la couleur en EEPROM
{
if(mode_affi != COUL) {return;} // pour ne pas détecter le clic sur un bouton invisible !
uint16_t c1 = GRIS_6;
uint16_t c2 = JAUNE;
test_clic_boutons(&bt_coul_to_EEPROM );
if (bt_coul_to_EEPROM.cliked)
{
bt_coul_to_EEPROM.cliked = false;
bt_coul_to_EEPROM.selected = true;
bt_coul_to_EEPROM.affiche(NOIR, VERT, 1);
EEPROM.writeShort(EEPROM_adrs_couleur, couleur_fond_ecran); // write 1 mot de 16 bits soit 2 octets
EEPROM.commit();
mode_affi = VUM;
init_affichages();
delay(200);
init_affichages(); //clignotement volontaire (indique que l'écriture a bien été effectuée)
delay(500);
}
}
void test_clic_bt_close1() // referme la box de saisie couleur fond d'écran et réaffiche le vu-mètre
{
if(mode_affi != COUL) {return;}
uint16_t c1 = GRIS_6;
uint16_t c2 = JAUNE;
test_clic_boutons(&bt_close1 );
if (bt_close1.cliked)
{
bt_close1.cliked = false;
bt_close1.selected = true;
bt_close1.affiche(NOIR, VERT, 1);
mode_affi = VUM;
init_affichages();
}
}
void affi_valeurs_RGB() // les 3 nombres près des boutons
{
uint16_t x = x0_choix_couleur;
//uint16_t y = y0_choix_couleur;
uint16_t z;
String s1;
TFT.setFreeFont(FF0); TFT.setTextColor(BLANC, NOIR);
s1 = String(cR);
z= bt_R_plus.y0;
TFT.fillRect(x+55, z+5, 20, 8, NOIR); // efface
TFT.drawString(s1, x+60, z+5);
s1 = String(cG);
z= bt_G_plus.y0;
TFT.fillRect(x+55, z+5, 20, 8, NOIR); // efface
TFT.drawString(s1, x+60, z+5);
s1 = String(cB);
z= bt_B_plus.y0;
TFT.fillRect(x+55, z+5, 20, 8, NOIR); // efface
TFT.drawString(s1, x+60, z+5);
}
void test_clic_1_bouton_couleur(TOUCH_BOUTON *bouton_i, uint8_t *cX, int8_t d )
{
uint16_t c1 = GRIS_3;
uint16_t c2 = BLANC;
uint16_t x = x0_choix_couleur;
uint16_t y = y0_choix_couleur;
test_clic_boutons(bouton_i);
if (bouton_i->cliked)
{
bouton_i->affiche(c1, c2, 1);
bouton_i->cliked=false;
bouton_i->selected=false;
int v = *cX;
v += d;
if(v<0) {v=0;}
if(v>64) {v=64;}
*cX = v;
String s1 = String(*cX );
uint16_t z= bouton_i->y0;
TFT.fillRect(x+55, z+5, 20, 8, NOIR); // efface
TFT.setFreeFont(FF0); TFT.setTextColor(BLANC, NOIR);
TFT.drawString(s1, x+60, z+5);
delay(100);
bouton_i->affiche(c1, c2, 1);
uint16_t couleur; // RGB_565
couleur = ( (cR<<11) | (cG<<5) | (cB) );
couleur_fond_ecran = couleur;
s1 = String(couleur);
TFT.fillRect(x+5, y+60, 40, 10, NOIR);
TFT.drawString(s1, x+5, y+60);
TFT.fillRoundRect(x+80, y+10, 40, 40, 5, couleur_fond_ecran); // grand carré de test couleur
}
}
void test_clic_boutons_couleurs()
{
if(mode_affi != COUL) {return;}
test_clic_1_bouton_couleur(&bt_R_plus, &cR, 1);
test_clic_1_bouton_couleur(&bt_R_moins, &cR, -1);
test_clic_1_bouton_couleur(&bt_G_plus, &cG, 1);
test_clic_1_bouton_couleur(&bt_G_moins, &cG, -1);
test_clic_1_bouton_couleur(&bt_B_plus, &cB, 1);
test_clic_1_bouton_couleur(&bt_B_moins, &cB, -1);
}
void test_clic_bouton_mute()
{
test_clic_boutons(&bt_mute );
bt_mute.affiche(NOIR, ROUGE, 1);
delay(100);
if (bt_mute.cliked)
{
bt_mute.cliked = false;
mute = ! mute;
Set_Mute(mute); // fonction située dans le fichier 'driverTEF6686_628.h'
bt_mute.selected = mute;
bt_mute.affiche(NOIR, ROUGE, 1);
if (! mute) {Tune_Frequence(frequence);}
delay(500);
}
}
void test_clic_bouton_Sleep()
{
test_clic_boutons(&bt_sleep );
//bt_sleep.affiche(NOIR, ROUGE, 1);
//delay(100);
if (bt_sleep.cliked)
{
bt_sleep.cliked = false;
bt_sleep.selected = true;
bt_sleep.affiche(NOIR, ROUGE, 1);
delay(100);
EEPROM.writeUInt(EEPROM_adrs_freq, frequence); // write 1 mot de 16 bits soit 2 octets
Serial.print("mode_s ici1: "); Serial.println(mode_s);
EEPROM.writeByte(EEPROM_adrs_mode, mode_s); // write 1 octet
EEPROM.commit();
delay(100);
esp_deep_sleep_start();
}
}
void test_clic_bouton_test()
{
test_clic_boutons(&bt_test );
bt_test.affiche(GRIS_2, VERT, 1);
delay(100);
if (bt_test.cliked)
{
bt_test.cliked = false;
bt_test.selected = true;
bt_test.affiche(GRIS_2, VERT, 1);
write_TFT_on_SDcard();
delay(100);
bt_test.selected = false;
bt_test.affiche(GRIS_2, VERT, 1);
}
}
void EE_RAZ()
{
boolean valider = false; // <-- ecrire "= true" pour rendre l'effacement possible
// (évite tout effacement accidentel et donc perte de centaines de fréquences...)
if(valider == false)
{
TFT.fillScreen(NOIR);
TFT.setFreeFont(FM9);
TFT.drawString("FONCTION VOLONTAIREMENT", 50, 120);
TFT.drawString("INACTIVE", 50, 140);
TFT.drawString("VOIR LE CODE SOURCE", 50, 160);
TFT.drawString("void EE_RAZ()", 50, 180);
delay(3000);
//setup();
init_affichages();
return;
}
// efface le contenu del'EEPROM, partie data fréquences, sans toucher aux 100 premiers octets
Serial.println("debut RAZ EEPROM");
for(uint16_t n = 0; n<1200; n+=4 ) // 300 x 4 bytes // OK
{
uint32_t valeur1;
valeur1 = 0;
EEPROM.writeUInt(100+n, valeur1); // les 100 premiers octets sont réservés (par moi)
}
EEPROM.commit();
Serial.println("fin RAZ EEPROM");
}
void test_clic_bouton_EE_RAZ()
{
uint16_t c1 = NOIR;
uint16_t c2 = VERT;
test_clic_boutons(&bt_EE_RAZ );
if(bt_EE_RAZ.cliked)
{
bt_EE_RAZ.cliked = false;
bt_EE_RAZ.selected = false;
bt_EE_RAZ.affiche(ROUGE, c1, 1);
EE_RAZ();
//EE_to_serial();
}
}
uint16_t EE_find_1ere_mem_libre(uint16_t adr0) // travaille directement sur l'EEPROM (en lecture uniquement!)
{
Serial.println("EE_find_1ere_mem_libre");
uint16_t n =0;
uint16_t adresse_lue;
uint32_t valeur_lue;
boolean ok = false;
while ((n<50) && (ok == false))
{
n += 4;
adresse_lue = adr0 + n;
valeur_lue = EEPROM.readUInt(adresse_lue); // 4 octets
Serial.print("valeur lue: "); Serial.println(valeur_lue);
if (valeur_lue == 0) {ok = true;}
}
Serial.print("trouve: "); Serial.println(n);
return adresse_lue;
}
boolean EE_find_if_present(uint16_t adr0, uint32_t F_i) // travaille directement sur l'EEPROM (en lecture uniquement!)
{
Serial.println("EE_find_if_present");
uint16_t n =0;
uint16_t adresse_lue;
uint32_t valeur_lue;
boolean ok = false;
while ((n<100) && (ok == false))
{
n += 4;
adresse_lue = adr0 + n;
valeur_lue = EEPROM.readUInt(adresse_lue); // 4 octets
if (valeur_lue == F_i) {ok = true;}
}
return ok;
}
void test_clic_bouton_EE_write()
{
uint16_t c1 = GRIS_6;
uint16_t c2 = VERT;
test_clic_boutons(&bt_EE_write );
if(bt_EE_write.cliked)
{
Serial.println("--------------------------------");
Serial.println("bouton_EE_write clic");
bt_EE_write.cliked = false;
bt_EE_write.selected = false;
bt_EE_write.affiche(GRIS_3, c1, 1);
delay (300);
bt_EE_write.cliked = false;
bt_EE_write.selected = false;
bt_EE_write.affiche(c1, c2, 1); // fugitif
//TFT.drawString("WRITE !", 5, 120);
//TFT.fillRect(5, 120, 50, 30, NOIR); // efface
uint16_t adr0;
uint16_t m0;
if (bande_SW)
{
adr0 = groupe_SW.adr_0;
m0 = EE_find_1ere_mem_libre(adr0);
}
if (bande_FM)
{
adr0 = groupe_FM.adr_0;
m0 = EE_find_1ere_mem_libre(adr0);
}
if (bande_AIR)
{
adr0 = groupe_AIR.adr_0;
m0 = EE_find_1ere_mem_libre(adr0);
}
if( ! EE_find_if_present(adr0, frequence)) // pour éviter les doublons
{
Serial.println("EEPROM.writeUInt");
Serial.print("m0="); Serial.println(m0);
Serial.print("frequence="); Serial.println(frequence);
EEPROM.writeUInt(m0, frequence);
EEPROM.commit();
delay(500);
load_GRP_FREQ_EEPROM();
}
else
{
Serial.print("F=");
Serial.print(frequence);
Serial.println(" presente, NO write");
}
Serial.println("--------------------------------");
}
}
void test_clic_bouton_EE_read()
{
uint16_t c1 = GRIS_6;
uint16_t c2 = VERT;
test_clic_boutons(&bt_EE_read );
if(bt_EE_read.cliked)
{
bt_EE_read.cliked = false;
bt_EE_read.selected = false;
bt_EE_read.affiche(GRIS_3, c1, 1);
delay (300);
bt_EE_read.cliked = false;
bt_EE_read.selected = false;
bt_EE_read.affiche(c1, c2, 1); // fugitif
}
}
void test_clic_boutons_MODE() // FREQ - MEM
{
uint16_t c1 = NOIR;
uint16_t c2 = VERT;
uint16_t c3 = JAUNE;
bt_mode_FRQ.cliked = false;
bt_mode_MEM.cliked = false;
test_clic_boutons(&bt_mode_FRQ );
if (bt_mode_FRQ.cliked) // les boutons sont exclusifs
{
mode_s = _FRQ;
bt_mode_FRQ.selected = true;
bt_mode_MEM.selected = false;
affiche_frequence(frequence);
efface_numero_frq();
}
test_clic_boutons(&bt_mode_MEM );
if (bt_mode_MEM.cliked)
{
mode_s = _MEM;
bt_mode_MEM.selected = true;
bt_mode_FRQ.selected = false;
//affiche_box_FRQ(JAUNE);
affiche_frequence(frequence);
}
bt_mode_FRQ.affiche(c1, c2, 1);
bt_mode_MEM.affiche(c1, c3, 1);
}
void test_clic_boutons_BANDE() // SW, FM, AIR
{
uint16_t c1 = NOIR;
uint16_t c2 = VERT;
bt_SW.cliked = false;
bt_FM.cliked = false;
bt_AIR.cliked = false;
test_clic_boutons(&bt_SW );
if (bt_SW.cliked)
{
TFT.fillRect(x0_box_info+2, y0_box_info+2, 175, 12, couleur_fond_ecran); // efface
Serial.println("bt_SW.cliked");
bande_active = SW;
bt_SW.selected = true;
bt_FM.selected = false; // les boutons sont exclusifs
bt_AIR.selected = false;
efface_numero_frq();
boutons_preset_set_frequences();
clic_logiciel_bouton(&bt_station1);
}
test_clic_boutons(&bt_FM );
if (bt_FM.cliked)
{
Serial.println("bt_FM.cliked");
bande_active = FM;
bt_FM.selected = true;
bt_SW.selected = false;
bt_AIR.selected = false;
efface_numero_frq();
boutons_preset_set_frequences();
clic_logiciel_bouton(&bt_station1);
}
test_clic_boutons(&bt_AIR );
if (bt_AIR.cliked)
{
TFT.fillRect(x0_box_info+2, y0_box_info+2, 175, 12, couleur_fond_ecran); // efface
Serial.println("bt_AIR.cliked");
bande_active = AIR;
bt_AIR.selected = true;
bt_SW.selected = false;
bt_FM.selected = false;
efface_numero_frq();
boutons_preset_set_frequences();
clic_logiciel_bouton(&bt_station1);
}
bt_SW.affiche(c1, c2, 1);
bt_FM.affiche(c1, c2, 1);
bt_AIR.affiche(c1, c2, 1);
}
void test_1_bouton_preset(TOUCH_BOUTON_PRESET *bouton_i)
{
uint16_t c1 = GRIS_5;
uint16_t c2 = GRIS_1;
uint16_t c3 = JAUNE;
//bouton_i->affiche(c1, c2, 1);
if (mode_affi == VUM) { bouton_i->affiche(c1, c2, 1); }
test_clic_boutons(bouton_i );
if (bouton_i->cliked)
{
bouton_i->cliked = false;
bouton_i->selected = true;
bouton_i->affiche(c1, c2, 1);
if (mode_affi == VUM)
{
mode_s = _MEM;
bt_mode_MEM.selected = true;
bt_mode_FRQ.selected = false;
efface_numero_frq();
bt_mode_MEM.affiche(c1, c3, 1);
bt_mode_FRQ.affiche(c1, c2, 1);
frequence = bouton_i->frequence;
affiche_frequence(frequence);
TFT.fillRoundRect(10, 3, 100, 10, 3, c1); // efface
TFT.setTextColor(JAUNE, NOIR);
TFT.drawString(bouton_i->nom, 10, 4);
Tune_Frequence(bouton_i->frequence);
bt_mute.selected = false;
bt_mute.affiche(NOIR, ROUGE, 1);
}
if (mode_affi == COUL)
{
//uint16_t couleur;
//couleur = bouton_i->couleur;
couleur_fond_ecran = bouton_i->couleur;
init_affichages();
}
//bouton_i->affiche(c1, c2, 1);
}
}
void deselect_boutons_presets()
{
bt_station1.selected = false;
bt_station2.selected = false;
bt_station3.selected = false;
bt_station4.selected = false;
bt_station5.selected = false;
bt_station6.selected = false;
bt_station7.selected = false;
bt_station8.selected = false;
}
void test_boutons_presets()
{
uint16_t c1 = NOIR;
uint16_t c2 = BLEU;
deselect_boutons_presets();
test_1_bouton_preset(&bt_station1);
test_1_bouton_preset(&bt_station2);
test_1_bouton_preset(&bt_station3);
test_1_bouton_preset(&bt_station4);
test_1_bouton_preset(&bt_station5);
test_1_bouton_preset(&bt_station6);
test_1_bouton_preset(&bt_station7);
test_1_bouton_preset(&bt_station8);
deselect_boutons_presets();
}
void affiche_signal(uint16_t x, uint16_t y, uint16_t dx, int16_t valeur)
{
TFT.fillRect(x, y, dx, 8, NOIR); // efface
if(valeur<0) {valeur =0;}
if(valeur > dx) {valeur = dx;}
TFT.drawRect(x, y, dx, 5, couleur_traits);
TFT.fillRect(x, y, valeur, 5, JAUNE);
}
void affiche_1_bargraph(uint16_t x, uint16_t y, uint16_t dx, int16_t valeur, uint16_t couleur)
{
TFT.fillRect(x, y, dx+40, 8, NOIR); // efface
TFT.drawString(String(valeur), x, y);
if(valeur<0) {valeur =0;}
if(valeur > dx) {valeur = dx;}
TFT.drawRect(x+40, y, dx, 5, couleur_traits);
TFT.drawRect(x+40, y, valeur, 5, couleur);
}
void affiche_bars_graph()
{
affiche_1_bargraph(170, 150, 100, level/10, VERT);
affiche_1_bargraph(170, 160, 100, usn, JAUNE);
affiche_1_bargraph(170, 170, 100, wam, BLEU_CLAIR);
affiche_1_bargraph(170, 180, 100, offset, BLANC);
}
String int_to_hex(uint16_t nb)
{
char symb[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
uint8_t A = (nb & 0b1111000000000000) >>12;
uint8_t B = (nb & 0b0000111100000000) >>8;
uint8_t C = (nb & 0b0000000011110000) >>4;
uint8_t D = (nb & 0b0000000000001111);
String s1 = String(symb[A]) + String(symb[B]) + String(symb[C]) + String(symb[D]) ;
return s1;
}
void traite_signal_RDS()
{
Get_RDS_Data ( &status, &A_block, &B_block, &C_block, &D_block, &dec_error);
/*
A_Block always contains the 16-bit program identifier.
The first 11 bits (bits 15–5) of block 2 are also the same in all groups.
La Liste des codes RDS autorisés se trouve ici : https://www.csa.fr/maradiofm/radiords_tableau
pour les autres blocks, voir :
https://en.wikipedia.org/wiki/Radio_Data_System
(c'est sans doute logique mais terriblement indigeste !!!)
*/
TFT.fillRect(x0_box_info+2, y0_box_info+2, 175, 12, couleur_fond_ecran); // efface
String s1 = int_to_hex(A_block);
String s2, s3;
TFT.setTextColor(BLANC, GRIS_5);
for(int n = 0; n<=nb_stations_RDS-1; n++)
{
s2 = codesRDS[n];
//Serial.println(s2);
s3 = s2.substring(0, 4);
if (s3 == s1)
{
TFT.drawString(s2, x0_box_info+5, y0_box_info +4);
return; // on ne continue pas à boucler si trouvé
}
else if (n == nb_stations_RDS-1) // pas trouvé...
{
TFT.drawString(s1, x0_box_info+5, y0_box_info +4);
return;
}
}
}
void loop()
{
if (ts.tirqTouched() && ts.touched())
{
TS_Point p = ts.getPoint();
printTouchToDisplay(p);
test_clic_6_boutons_frq();
test_clic_boutons_plus_moins();
test_clic_bouton_mute();
test_clic_bouton_Sleep();
test_clic_bouton_test();
test_clic_boutons_MODE();
test_clic_boutons_BANDE();
test_boutons_presets();
uint8_t n_touch = numPad1.test_clic();
traite_touches_pad(n_touch);
test_clic_bouton_EE_RAZ();
test_clic_bouton_EE_write();
test_clic_bouton_EE_read();
test_clic_bt_affi_box_couleurs();
test_clic_boutons_couleurs();
test_clic_bt_close1();
test_clic_bt_RST_affi();
test_clic_bt_coul_to_EEPROM();
}
// la limitation SW max = 28MHz est due au module TEF6686 lui-même
if (frequence >= 138000) {frequence = 138000;} //138 MHz limite à cause SW max = 28MHz et conv AirBand = 110 MHz
if (frequence < 1500) {frequence = 1500;} // 1.5 MHz
if (compteur1 >= 5)
{
compteur1 =0;
uint8_t module;
if(bande_active == FM) {module = 32;} else {module = 33;}
Get_Quality( module, &status, &level, &usn, &wam, &offset, &bandwidth, &mod, &snr );
float signal_sur_bruit = level - 1.5 * usn; // marche à peu près bien pour la FM.
// toutefois additionner une valeur linéaire avec une autre logarithmique... pas top !
// faut que je vois ça de plus près !
float diff = signal_sur_bruit - position_aiguille;
if(diff > 30.0) {diff = 30.0;}
if(diff < -30.0) {diff = -30.0;} // évite une trop grande réaction au sortir du mode 'mute'
// supprime les tremblements de l'aiguille
position_aiguille += diff / 10.0;
//affiche_bars_graph();
affiche_signal(170, 90, 60, mod/2);
if ((mode_affi == VUM) && (! mute) ) { plotAiguille(position_aiguille/6.0); }
if ((mode_affi == VUM) && (mute) ) { plotAiguille(0); }
}
if (compteur2 >= 100)
{
compteur2 =0;
if(bande_active == FM) {traite_signal_RDS();}
/*
TFT.drawString(
String(A_block) + " " +
String(B_block) + " " +
String(C_block) + " " +
String(D_block) + " ", x0_box_info+5, y0_box_info +4);
*/
}
#ifdef _SD_CARD
if (compteur3 == 2000)
{
write_TFT_on_SDcard(); // attention : incompatible avec le TOUCHPAD
}
#endif
delay(10);
compteur1++;
compteur2++;
compteur3++;
}
/** ***************************************************************************************
CLASS TOUCH_BOUTON // affiche un nombre ou un petit texte dans un rectangle
ainsi que (en plus petit) deux valeurs supplémentaires, par ex: les valeurs mini et maxi
********************************************************************************************/
// Constructeur
TOUCH_BOUTON::TOUCH_BOUTON()
{
}
// Constructeur
TOUCH_BOUTON_PRESET::TOUCH_BOUTON_PRESET()
{
}
void TOUCH_BOUTON::init(uint16_t xi, uint16_t yi, uint16_t dxi, uint16_t dyi, uint16_t dri)
{
x0 = xi;
y0 = yi;
dx = dxi;
dy = dyi;
dr = dri;
cliked = false;
selected = false;
}
void TOUCH_BOUTON::affiche(uint16_t coul_fill_unselect, uint16_t coul_fill_select, uint8_t n_font)
{
//uint16_t c1 = NOIR;
uint16_t couleur_contour = GRIS_5;
//uint16_t couleur_texte = BLANC);
if(selected)
{
TFT.fillRoundRect(x0, y0, dx, dy, dr, coul_fill_select);
TFT.setTextColor(NOIR);
}
else
{
TFT.fillRoundRect(x0, y0, dx, dy, dr, coul_fill_unselect); // efface
TFT.drawRoundRect(x0, y0, dx, dy, dr, couleur_contour); // retrace juste le contour
TFT.setTextColor(BLANC);
}
//FM9 FMB9 FSS9... voir le fichier Free_Fonts.h
if (n_font == 1) { TFT.setFreeFont(FF0); }
if (n_font == 2) { TFT.setFreeFont(FM9); }
if (n_font == 3) { TFT.setFreeFont(FMB9); }
if (n_font == 4) { TFT.setFreeFont(FSS9); }
TFT.drawString(s, x0+5, y0+5);
}
/** ***************************************************************************************
CLASS NUMPAD
********************************************************************************************/
// Constructeur
NUM_PAD::NUM_PAD()
{
pad[0] = bt_num0;
pad[1] = bt_num1;
pad[2] = bt_num2;
pad[3] = bt_num3;
pad[4] = bt_num4;
pad[5] = bt_num5;
pad[6] = bt_num6;
pad[7] = bt_num7;
pad[8] = bt_num8;
pad[9] = bt_num9;
}
void NUM_PAD::init(uint16_t xi, uint16_t yi, boolean fond) // si fond =false, ne resessine que les boutons
{
x0 = xi;
y0 = yi;
int x, y;
int dx = 25; // taille x d'une touche
int dy = 23; // taille y d'une touche
if(fond == true) {TFT.fillRect(x0, y0, 3*dx +6, 4*dy +7, NOIR);}
uint16_t c1 = GRIS_5;
uint16_t c2 = JAUNE;
x = x0+2;
y = y0+2;
for(uint8_t n =1; n<10; n++)
{
pad[n].init(x, y, dx, dy, 3);
pad[n].s=String(n);
pad[n].affiche(c1, c2, 2);
x += dx+1;
if (x > (x0 + 3*dx)) {x = x0+2; y += dy+1; }
}
pad[0].init(x, y, dx, dy, 3); pad[0].s="0"; pad[0].affiche(c1, c2, 2); x += dx+1;
bt_point.init(x, y, dx, dy, 3); bt_point.s="."; bt_point.affiche(c1, c2, 2);
x += dx+1;
bt_ok.init(x, y, dx, dy, 3); bt_ok.s="ok";
bt_ok.affiche(c1, c2, 1);
}
uint8_t NUM_PAD::test_clic()
{
// zone des boutons du claver
if ( (( x_touch > x0) && (x_touch < x0 + 100)) && (( y_touch > y0) && (y_touch < y0 + 130)))
{
uint8_t num_touche =0;
for(uint8_t n = 0; n<10; n++)
{
test_clic_boutons(&pad[n] ); if(pad[n].cliked) {num_touche=n; n_appui ++;}
}
test_clic_boutons(&bt_point ); if(bt_point.cliked) {num_touche=254; } // bouton "."
test_clic_boutons(&bt_ok ); if(bt_ok.cliked) {num_touche=255; n_appui ++;} // bouton "ok"
delay(100);
init(x0, y0, false); // 'false' évite le clignotement lorsqu'on repeint le fond noir
return num_touche;
}
return 253;
}
/** ***************************************************************************************
CLASS GROUPE_FREQUENCES // objet image d'un bloc mémoire en EEPROM
permet diverses manipulations en RAM (tri...) sans toucher à l'EEPROM
********************************************************************************************/
// Constructeur
GROUPE_FREQUENCES::GROUPE_FREQUENCES()
{
}
void GROUPE_FREQUENCES::load_bloc()
{
// partie données de fréquences (adrs >100)
Serial.println("load_bloc()");
//Serial.print("adr_0= "); Serial.println(adr_0);
uint32_t valeur_lue;
for(uint16_t n = 0; n<100; n++ ) // chaque uint32_t lu = 4 Bytes
{
valeur_lue = EEPROM.readUInt(adr_0 + n*4); // 4 octets
G_freq[n]=valeur_lue;
}
}
void GROUPE_FREQUENCES::tri_bloc()
{
Serial.println("tri_block()");
// tri par bulles
uint32_t F1=0, F2=0;
uint32_t Fi;
uint16_t i_max = 100;
uint16_t p_max = 100;
for(uint16_t p=0; p<p_max; p++)
{
for(int n=0; n<i_max-1; n++)
{
F1=G_freq[n];
F2=G_freq[n+1];
if(F1 > F2)
{
Fi = G_freq[n];
G_freq[n] = G_freq[n+1];
G_freq[n+1] = Fi;
}
}
}
// compte le nombre de fréquences != 0
uint16_t nombre =0;
for(uint16_t n = 0; n<100; n++ )
{
F1 = G_freq[n];
if(F1 != 0) { nombre++; }
}
nb_freq = nombre;
// recherche première fréquence non nulle
uint16_t n2=0;
F1 =0;
while ((F1==0) && (n2<100))
{
F1=G_freq[n2];
n2++;
}
adr_1ere_frq = n2-1;
}
void GROUPE_FREQUENCES::bloc_to_serial() // pour tests, avec CuteCom sous Linux
{
Serial.println("bloc_to_serial()");
uint32_t valeur_lue;
uint16_t nombre =0;
for(uint16_t n = 0; n<100; n++ )
{
valeur_lue = G_freq[n];
if(valeur_lue != 0) // n'affiche pas les emplacements vides
{
nombre++;
Serial.println(valeur_lue);
}
}
Serial.print(nombre); Serial.println(" frequences");
Serial.print("adr 1ere Frq= "); Serial.println(adr_1ere_frq);
Serial.print("1ere Frq= "); Serial.println(G_freq[adr_1ere_frq]);
}