/* ************************************************************************************
Gene UHF et Wobulateur AD9850 + ADF4351
par Silicium628
pour ma carte (fab : JLCPCB) ESP32 Wroom + afficheur 2.8" TFT 240x320 + SDcard
Cette version utilise la SDcard
************************************************************************************ */
// REMARQUES:
// 1) lorsque la carte est connectée sur un bus USB de l'ordinateur,
// un terminal série tel que CuteCom affichera beaucoup de choses en temps réel.
// 2) Pour s'y retrouver dans le code, le plus simple est de partir de la fonction 'loop()' qui appelle les autres
// 3) Le fichier User_Setup dans le dossier 'lib/TFT_eSPI' est spécifique à cette configuration
// pour ce qui concerne les connexions mais aussi les limitations de fréquence du bus SPI
#include <Arduino.h>
#include "main.h"
#include "ADF4351-ESP32.h"
#include "AD9850-ESP32.h"
String version = "2.10.1";
#include "FS.h"
#include "SD.h"
#include "Wire.h"
#include <stdint.h>
#include <Free_Fonts.h>
#include "TFT_eSPI.h" // Hardware-specific library
#include "SPI.h"
#include "Digit_Font.h"
#include <XPT2046_Touchscreen.h>
#include "constantes2_628.h"
#include "Couleurs_AEC.h"
int style = 0; // 0 bleu, 1 vert, 3 jaune
ADF4351 CarteADF4351;
AD9850 CarteAD9850;
#define SPI_READ_FREQUENCY 16000000
#define XPT2046_IRQ 36
#define XPT2046_MOSI 32 //T_DI 32
#define XPT2046_MISO 39 //T_DO 39
#define XPT2046_CLK 25
#define XPT2046_CS 33
const int GPIO_SDA = 21;
const int GPIO_SCL = 22;
const int analogPin = 35;
const int boutonPin1 = 4; // GPIO4
//const int GPIO_BL = 4; // pour LED backlight ILI9341- INUTILISE POUR CETTE APPLICATION - relier backlight à +3v3
// donc le GPIO4 est libre...
const int _DX = 320;
const int _DY = 240;
SPIClass mySpi = SPIClass(VSPI);
XPT2046_Touchscreen ts(XPT2046_CS, XPT2046_IRQ);
SPIClass mySpi2 = SPIClass(HSPI);
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); // grands chiffres en haut
TFT_eSprite sprite_freq_W_min = TFT_eSprite(&TFT);
TFT_eSprite sprite_freq_W_max = TFT_eSprite(&TFT);
uint16_t FRQ_x0;
uint16_t FRQ_y0;
const uint64_t F_min_AD9850 = 1;
const uint64_t F_max_AD9850 = 52000000; // 52 MHz , au delà le signal est pourri !
const uint64_t F_min_ADF4351 = 33000000;
const uint64_t F_max_ADF4351 = 4400000000;
struct ETALON_TS // etalon touch screen
{
int16_t x0;
int16_t dx;
int16_t y0;
int16_t dy;
};
ETALON_TS eTS;
struct POINT
{
uint16_t x;
uint16_t y;
};
// coordonnées des points de calibrage de l'écran tactile
// (calibration ? étalonnage ?? ajustage ??? boaf, m'enfin !!)
POINT A, B;
uint8_t SDcardOk=0;
uint16_t x_touch, y_touch;
uint16_t memo_x_touch, memo_y_touch;
uint16_t compte1=0;
uint16_t compte2=0;
uint8_t num_capture = 0;
uint64_t frequence=10000;
uint32_t pas_W = 0; // pas (de wobulation)
//uint64_t freq_W_min;
uint64_t freq_W_max;
uint64_t Fmin, Fmax;
double F_9850; // fréquence à envoyer à l'AD9850 (en 1/10 Hz)
double F_4351; // fréquence à envoyer à l'ADF4351 (en MHz avec décimales)
//boolean le_pas_est_choisi = false;
boolean soft_setup =false;
boolean do_capt_screen = false;
boolean stop1=false;
uint16_t JAUNE_chiffres = 65504;
uint16_t VERT_chiffres = 2016;
TOUCH_BOUTON bt_RAZ;
//fréquences presets
TOUCH_BOUTON bt_455k;
TOUCH_BOUTON bt_4M;
TOUCH_BOUTON bt_10_7M;
TOUCH_BOUTON bt_27M;
TOUCH_BOUTON bt_35M;
TOUCH_BOUTON bt_41M;
TOUCH_BOUTON bt_144M;
TOUCH_BOUTON bt_432M;
TOUCH_BOUTON bt_2400M;
TOUCH_BOUTON bt_AD9850;
TOUCH_BOUTON bt_ADF4351;
TOUCH_BOUTON bt_mode_GENE;
TOUCH_BOUTON bt_mode_WOBU;
TOUCH_BOUTON bt_STOP_1; // du balayage fréquenciel
TOUCH_BOUTON bt_STOP_2; // de la boucle de déplacement du curseur
TOUCH_BOUTON bt_polarite;
TOUCH_BOUTON bt_gain_P; // gain +
TOUCH_BOUTON bt_gain_M; // gain -
TOUCH_BOUTON bt_pas_P; // incrémente le pas de wobulation suivant la suite 1,2,5...
TOUCH_BOUTON bt_pas_M;
uint8_t num_pas=0;
TOUCH_BOUTON bt_TEST;
CHF_PAD chf_pad1;
enum OUTPUT_MODE {MODE_9850, MODE_4351};
OUTPUT_MODE out_mode1;
OUTPUT_MODE memo_out_mode1;
enum FONCTION_MODE {MODE_ACCUEIL, MODE_GENE, MODE_WOBU};
FONCTION_MODE f_mode1;
//FONCTION_MODE memo_f_mode1;
enum POLARITE {_DIR, _INV};
POLARITE polarite1 = _DIR;
uint32_t liste_pas_W_a[3] = {1, 2, 5}; // num 0 à 3
uint64_t liste_pas_W_b[7] = {1, 10, 100, 1000, 10000, 100000, 1000000}; // numéros 0 à 6
void init_sprites()
{
sprite_frq.createSprite(315, 45);
sprite_frq.setTextDatum(MR_DATUM); // alignement du texte
sprite_freq_W_min.createSprite(80, 8);
sprite_freq_W_max.createSprite(80, 8);
}
void init_variables_globales()
{
FRQ_x0 = 2;
FRQ_y0 = 30;
//frequence = 4123456789; // 4.12 GHz
frequence = 60000000; // 60MHz
}
void init_1_bouton(uint8_t n_font, uint16_t xi, uint16_t yi, uint8_t dx, uint8_t dy, String si, TOUCH_BOUTON *bouton_i)
{
bouton_i->init(xi, yi, dx, dy, 3, GRIS_5);
bouton_i->cliked = false;
bouton_i->selected = false;
bouton_i->label = si;
bouton_i->affiche(BLANC, VERT, n_font);
}
void test_bouton_physique1()
{
int v = digitalRead(boutonPin1);
if (v == 0) {capture_ecran();}
}
// Fonction optimisée pour l'afficheur ILI9341 320x240 avec la library 'TFT_eSPI'
// ne convient PAS pour les ESP32 Wroom + afficheur 3.5" TFT 480x320
void capture_ecran() // enregistre image bmp 320x240 RGB565 (5+6+5 = 16bits/px)
{
Serial.println("capture_ecran()");
if (SDcardOk==0)
{
Serial.println("SDcard absente, capture ecran impossible");
return;
}
int32_t x, y;
uint16_t color565;
uint8_t lineBuffer8[(320*2)];
uint16_t lineBuffer16[320];
uint8_t octet_A, octet_B;
String s1, s2;
s1 ="/bmp565/capture";
s1 += String(num_capture);
s1 += ".bmp" ;
Serial.print("s1= "); Serial.println(s1);
while(SD.exists(s1) && num_capture <= 50)
{
num_capture ++;
s1 ="/bmp565/capture";
s1 += String(num_capture);
s1 += ".bmp" ;
}
if (num_capture >= 50)
{
TFT.setTextColor(BLANC, NOIR);
TFT.setFreeFont(FF1);
TFT.drawString("Nb de capture max atteint", 20, 100);
TFT.setFreeFont(FF0);
TFT.drawString("Voir sur la SDcard, dans /bmp565/", 20, 120);
}
File file1 = SD.open(s1, FILE_WRITE); // crée le fichier si pas présent
delay(20);
if (file1)
{
// création entête bmp565 - 138 octets; voir bmp565_header[] dans le fichier main.h
for(uint8_t i=0; i<138; i++) { file1.write(bmp565_header[i]); }
TFT.setTextColor(VERT, NOIR);
for (int16_t y=239; y>=0; y--)
{
TFT.readRect(0, y, 320, 1, lineBuffer16); // lit une ligne
s2=String(y/24);
TFT.drawString(s2, 2, 2); // pour terminer par une écriture
uint16_t i=0;
for (int16_t x=0; x<320; x++) //320
{
uint16_t color565px = lineBuffer16[x]; // BBBBBrrr rrrVVVVV
octet_A = (color565px & 0b1111111100000000) >> 8;
octet_B = (color565px & 0b0000000011111111);
lineBuffer8[i] = octet_A;
lineBuffer8[i+1] = octet_B;
i+=2;
}
file1.write(lineBuffer8, sizeof(lineBuffer8));
}
file1.close();
num_capture ++;
// TFT.fillScreen(NOIR);
TFT.setTextColor(BLANC, NOIR);
TFT.setFreeFont(FF1);
TFT.drawString("Capture OK", 20, 120);
TFT.drawString(s1, 20, 140);
Serial.println("-----------------------");
Serial.println("Capture OK");
delay(2000);
}
}
void printTouchToDisplay() // pour TEST positions lors de la conception de l'interface graphique
{
// dessine une petite croix jaune au points d'appuis du stylet
init_1_bouton(1, 235, 114, 30, 15, "TEST", &bt_TEST);
uint16_t memo_seg_H[22];
uint16_t memo_seg_V[22];
uint16_t memo_x, memo_y;
TFT.setFreeFont(FM9);
TFT.setTextColor(BLEU_CLAIR, NOIR);
//TFT.drawString("TEST TOUCH screen", 80, 120);
TFT.readRect(x_touch-10, y_touch, 20, 1, memo_seg_H);
TFT.readRect(x_touch, y_touch-10, 1, 20, memo_seg_V);
while(1)
{
if (ts.tirqTouched() && ts.touched())
{
get_XY_touch();
TFT.readRect(x_touch-10, y_touch, 20, 1, memo_seg_H); // memorise image avant de tracer le trait
delay(10);
TFT.pushRect(memo_x_touch-10, memo_y_touch, 20, 1, memo_seg_H); // efface avec l'image enregistrée
delay(10);
TFT.drawFastHLine(x_touch-10, y_touch, 20, JAUNE);
delay(10);
TFT.readRect(x_touch, y_touch-10, 1, 20, memo_seg_V); // memorise image avant de tracer le trait
delay(10);
TFT.pushRect(memo_x_touch, memo_y_touch-10, 1, 20, memo_seg_V); // efface avec l'image enregistrée
delay(10);
TFT.drawFastVLine(x_touch, y_touch-10, 20, JAUNE);
String s1;
s1 = String(x_touch)+ " ";
TFT.drawString(s1, 120, 130);
s1 = String(y_touch)+ " ";
TFT.drawString(s1, 120, 154);
delay(10);
test_clic_bouton_TEST();
}
}
}
void affiche_box_FRQ(uint16_t couleur) // autour de la fréquence (gros chiffres)
{
TFT.drawRect(0, FRQ_y0 -17, 319, 48, couleur);
}
void acquisition_reponse()
{
uint16_t valeurLue = analogRead(analogPin); // = 0..4095
}
void out_frequence()
{
if (out_mode1 == MODE_9850)
{
F_9850 = 10.0 * frequence;
CarteAD9850.out_F(F_9850);
}
if (out_mode1 == MODE_4351)
{
F_4351 = (double) frequence / 1e6;
CarteADF4351.setFreq(F_4351);
CarteADF4351.Write_All_Register();
}
}
void affiche_frequence(uint64_t frq)
{
uint16_t couleur_chiffres;
uint16_t couleur_fond;
if(style == 0) { couleur_chiffres = VERT_chiffres; couleur_fond = NOIR; }
if(style == 1) { couleur_chiffres = BLANC; couleur_fond = BLEU; }
if(style == 2) { couleur_chiffres = JAUNE_chiffres; couleur_fond = NOIR; }
sprite_frq.fillRect(0, 0, 320, 45, couleur_fond); // couleur_fond efface
sprite_frq.setTextColor(couleur_chiffres, couleur_fond);
String Str_frq = formatage_frq(frq); // ajoute les points (.) séparateurs des milliers
sprite_frq.drawString(Str_frq, 320, 30, 6); //320, 32, 6
sprite_frq.pushSprite(FRQ_x0, 14);
affi_mode();
out_frequence();
}
void encadre_chiffre(uint16_t x)
{
TFT.drawRect(x, 18, 28, 44, BLANC);
}
void efface_bande_boutons()
{
TFT.fillRect(0, 61, 319, 19, NOIR);
TFT.drawRect(0, 61, 319, 19, BLANC);
}
void affi_boutons_gene() // boutons presets de fréquences
{
efface_bande_boutons();
TFT.setFreeFont(FF0);
TFT.setTextColor(BLANC, NOIR);
TFT.drawString("presets->", 5, 65);
if (out_mode1 == MODE_9850)
{
uint16_t x = 60;
init_1_bouton(1, x, 65, 30, 10, "455k", &bt_455k); x+=35;
init_1_bouton(1, x, 65, 20, 10, "4M", &bt_4M); x+=25;
init_1_bouton(1, x, 65, 30, 10, "10.7", &bt_10_7M); x+=35;
init_1_bouton(1, x, 65, 25, 10, "27M", &bt_27M); x+=30;
}
if (out_mode1 == MODE_4351)
{
uint16_t x = 60;
init_1_bouton(1, x, 65, 25, 10, "35M", &bt_35M); x+=30;
init_1_bouton(1, x, 65, 25, 10, "41M", &bt_41M); x+=30;
init_1_bouton(1, x, 65, 30, 10, "144M", & bt_144M); x+=35;
init_1_bouton(1, x, 65, 30, 10, "432M", & bt_432M); x+=35;
init_1_bouton(1, x, 65, 30, 10, "2.4G", & bt_2400M);
}
TFT.drawRect(1, 61, 319, 19, BLANC);
}
void affi_select_PAS()
{
efface_bande_boutons();
init_1_bouton(1, 5, 63, 40, 15, "PAS-", &bt_pas_P);
init_1_bouton(1, 55, 63, 40, 15, "PAS+", &bt_pas_M);
}
uint64_t calcul_pas_w(uint8_t n) // progression 1,2,5,10,20...[5e6]re
{
if (n>21) {return 0;}
int b=0;
for(int i=0; i<7; i++)
{
if(n<3) {return liste_pas_W_a[n] * liste_pas_W_b[b];}
b++; n-=3;
}
return 0;
}
void init_boutons_choix_MODULE()
{
init_1_bouton(2, 45, 90, 90, 25, " AD9850", &bt_AD9850);
init_1_bouton(2, 175, 90, 90, 25, " ADF4351", &bt_ADF4351);
}
void init_boutons_choix_MODE()
{
init_1_bouton(1, 80, 0, 60, 15, "GENE", &bt_mode_GENE);
init_1_bouton(1, 160, 0, 60, 15, "WOBU", &bt_mode_WOBU);
}
void init_affichages()
{
Serial.println("init_affichages()");
TFT.fillRect(0, 0, 319, 239, NOIR);
TFT.setTextColor(BLANC, NOIR);
TFT.drawRect(0, 0, 319, 240, BLANC); // cadre principal pourtour de l'écran
//TFT.setFreeFont(FF0);
//TFT.setTextColor(BLANC, BLEU);
//String s1 = "v:" + version;
//TFT.drawString(s1, 2, 2);
while (!Serial && (millis() <= 1000));
TFT.setFreeFont(FF0);
init_1_bouton(1, 285, 0, 30, 12, "RAZ", &bt_RAZ);
affi_boutons_gene();
/*
TFT.fillRect(3, 80, 115, 3, ORANGE); // barres horizontales colorées
TFT.fillRect(135, 80, 105, 3, VERT);
TFT.setFreeFont(FF0);
TFT.setTextColor(ORANGE, NOIR);
TFT.drawString("AD9850", 45, 80);
TFT.setTextColor(VERT, NOIR);
TFT.drawString("ADF4351", 165, 80);
*/
affiche_box_FRQ(GRIS_3); // autour de la fréquence (gros chiffres JAUNE ou VERT)
bt_RAZ.affiche(BLANC, VERT, 1);
bt_TEST.affiche(BLANC, VERT, 1);
TFT.drawRect(0, 0, 319, 240, BLANC); // cadre principal pourtour de l'écran
}
void affi_page_info()
{
// affiche une page d'information:
TFT.fillScreen(NOIR);
TFT.setTextColor(BLANC, NOIR);
TFT.setFreeFont(FF1);
uint16_t y=0;
TFT.drawString("DOUBLE GENE UHF - WOBULATEUR", 0, y); y+=40;
TFT.setTextColor(ORANGE, NOIR);
TFT.drawString("AD9850 -> 0 to 35Hz MHz", 0, y); y+=20;
TFT.setTextColor(VERT, NOIR);
TFT.drawString("ADF4351 -> 35 MHz to 4.4 GHz", 0, y); y+=40;
TFT.setTextColor(BLANC, NOIR);
TFT.setFreeFont(FF0);
String s1="version " + version;
TFT.drawString(s1, 0, y); y+=20;
TFT.setTextColor(CYAN, NOIR);
TFT.setFreeFont(FF1);
TFT.drawString("Silicium628", 0, y); y+=40;
delay(1000);
}
void init_SDcard()
{
Serial.println("---------------------");
Serial.println("init_SDcard()");
String s1;
TFT.fillRect(0, 0, 480, 320, NOIR); // efface tout l'écran
TFT.setTextColor(BLANC, NOIR);
TFT.setFreeFont(FF1);
if(!SD.begin(5, mySpi2))
{
Serial.println("Card Mount Failed");
SDcardOk=0;
}
else
{
Serial.println("SDcard OK");
SDcardOk=1;
TFT.fillRect(0, 0, 480, 320, VERT);
delay(100);
}
uint8_t cardType = SD.cardType();
if(cardType == CARD_NONE)
{
Serial.println("NO SDcard");
SDcardOk=0;
return;
}
Serial.print("SDcard Type: ");
if(cardType == CARD_SD) {Serial.print("SDSC");}
else if(cardType == CARD_SDHC) {Serial.println("SDHC");}
uint32_t cardSize = SD.cardSize() / (1024 * 1024);
s1=(String)cardSize + " GB";
Serial.println(s1); Serial.println();
delay (100);
TFT.fillRect(0, 0, 480, 320, NOIR); // efface
}
uint16_t read_16(File fp)
{
uint8_t low;
uint16_t high;
low = fp.read();
high = fp.read();
return (high<<8)|low;
}
uint32_t read_32(File fp)
{
uint16_t low;
uint32_t high;
low = read_16(fp);
high = read_16(fp);
return (high<<8)|low;
}
void affi_image_from_SD(String filename, uint16_t x0, uint16_t y0)
{
Serial.println("----------------------------");
Serial.println("affi_image_from_SD()");
uint8_t bmp_data[2]={0,0};
uint8_t a, b;
uint16_t x=0;
uint16_t y=0;
int16_t xmax;
uint32_t seekOffset;
uint16_t w, h, row, col;
File fp = SD.open(filename, "r");
if (!fp) { Serial.println("ERREUR open file on SD"); return; }
uint16_t etiq1 = read_16(fp);
// test bmp_header
if (etiq1 == 0x4D42)
{
read_32(fp);
read_32(fp);
seekOffset = read_32(fp);
Serial.print("seekOffset ="); Serial.println(seekOffset); // 138
Serial.print("seekOffset= "); Serial.println(seekOffset);
read_32(fp);
w = read_32(fp);
h = read_32(fp);
Serial.print("w= "); Serial.println(w); // 75
Serial.print("h= "); Serial.println(h); // 50
Serial.println(read_16(fp)); // 1
Serial.println(read_16(fp)); // 16
Serial.println(read_16(fp)); // 3
fp.seek(seekOffset);
}
y += h;
xmax = w;
if(xmax%2 == 1) {xmax +=1;}
uint16_t padding = (4 - ((w * 2) & 2)) & 2;
uint8_t lineBuffer[(w*2) + padding];
for (row = 0; row < h; row++)
{
fp.read(lineBuffer, sizeof(lineBuffer));
uint8_t* bptr = lineBuffer;
uint16_t* tptr = (uint16_t*)lineBuffer;
for (uint16_t col = 0; col < w; col++)
{
a = *bptr++;
b = *bptr++;
*tptr++ = (a <<8 | b);
}
TFT.pushImage(x0 + x, y0 + y, w, 1, (uint16_t*)lineBuffer);
y--;
}
fp.close();
}
void write_fichier_params() // sur la SDcard
{
Serial.println("write fichier '/params.txt'");
File file1 = SD.open("/params.txt", FILE_WRITE);
String s1;
/*
s1 ="[couleur_fond]";
s1 += "<";
s1 += String(couleur_fond_ecran);
s1 +=">";
file1.println(s1);
*/
s1 ="[frequence]";
s1 += "<";
s1 += String(frequence);
s1 +=">";
file1.println(s1);
s1 ="[Ax]";
s1 += "<";
s1 += String(A.x);
s1 +=">";
file1.println(s1);
s1 ="[Ay]";
s1 += "<";
s1 += String(A.y);
s1 +=">";
file1.println(s1);
s1 ="[Bx]";
s1 += "<";
s1 += String(B.x);
s1 +=">";
file1.println(s1);
s1 ="[By]";
s1 += "<";
s1 += String(B.y);
s1 +=">";
file1.println(s1);
file1.close();
delay(100);
}
void TS_calibrate() // calibrage de l'écran tactile
{
uint8_t L = 20;
boolean ok;
String s1;
TFT.setTextColor(BLANC, NOIR);
TFT.setFreeFont(FF1);
// traitement point A
TFT.fillScreen(NOIR);
TFT.drawString("Cliquez sur le point A", 20, 50);
delay(300);
TFT.drawFastVLine(10, 0, L, JAUNE);
TFT.drawFastHLine(0, 10, L, JAUNE);
ok = false;
while (! ok)
{
if (ts.tirqTouched() && ts.touched())
{
memo_y_touch = y_touch;
TS_Point p = ts.getPoint();
s1 = "Ax=" + String(p.x) + " "; TFT.drawString(s1, 50, 100);
s1 = "Ay=" + String(p.y) + " "; TFT.drawString(s1, 50, 120);
delay(100);
if( (p.x<600) && (p.y < 600)) // évite de valider une position irréaliste
{
A.x = p.x; // point A : variable globale
A.y = p.y;
ok = true;
}
}
}
// traitement point B
TFT.fillScreen(NOIR);
delay(300);
TFT.drawString("Cliquez sur le point B", 20, 70);
TFT.drawFastVLine(310, 230-L/2, L, JAUNE);
TFT.drawFastHLine(310-L/2, 230, L, JAUNE);
ok = false;
while (! ok)
{
if (ts.tirqTouched() && ts.touched())
{
memo_y_touch = y_touch;
TS_Point p = ts.getPoint();
s1 = "Bx=" + String(p.x) + " "; TFT.drawString(s1, 50, 150);
s1 = "By=" + String(p.y) + " "; TFT.drawString(s1, 50, 170);
delay(100);
if( (p.x>3600) && (p.y > 3400)) // évite de valider une position irréaliste
{
B.x = p.x;
B.y = p.y;
ok = true;
}
}
}
if(SDcardOk==1)
{
TFT.fillScreen(NOIR);
TFT.drawString("Ok", 20, 60);
TFT.setFreeFont(FF0);
TFT.drawString("Write fichier params sur la SD", 10, 90);
write_fichier_params();
delay(1000);
}
TFT.fillScreen(NOIR);
init_affichages();
//TS_verif();
//printTouchToDisplay(); // POUR TESTER LA CALIBRATION DE L'ECRAN TACTILE
}
String read_line_params(uint16_t line_num)
{
int i = 1;
char buffer[64];
String s;
File file = SD.open("/params.txt", "r");
while (file.available())
{
int l = file.readBytesUntil('\n', buffer, sizeof(buffer));
buffer[l] = 0;
if (line_num == i)
{
s = buffer;
file.close();
return(s);
}
i++;
}
return "";
}
int32_t extract_params(String ligne, String label)
{
String s2;
uint32_t valeur = 0;
int p1, p2;
p1 = ligne.indexOf('['); p2 = ligne.indexOf(']');
s2 = ligne.substring(p1+1, p2);
if (s2 == label)
{
p1 = ligne.indexOf('<'); p2 = ligne.indexOf('>');
s2 = ligne.substring(p1+1, p2);
valeur = s2.toInt();
return valeur;
}
return -1;
}
void read_params() // lecture du fichier '/params.txt' en SD
{
Serial.println("lecture du fichier '/params.txt' en SD");
String s1;
int valeur;
s1 = "Z";
uint8_t n=1;
while (s1 !="")
{
s1 = read_line_params(n); // retourne(par exemple): [couleur_fond]<267>
//valeur = extract_params(s1, "frequence");
//if(valeur != -1) {frequence = valeur;}
valeur = extract_params(s1, "Ax");
if(valeur != -1) {A.x = valeur;}
valeur = extract_params(s1, "Ay");
if(valeur != -1) {A.y = valeur;}
valeur = extract_params(s1, "Bx");
if(valeur != -1) {B.x = valeur;}
valeur = extract_params(s1, "By");
if(valeur != -1) {B.y = valeur;}
n++;
}
}
void affi_mode()
{
TFT.setFreeFont(FF0);
if (out_mode1 == MODE_9850)
{
TFT.setTextColor(VERT, NOIR);
TFT.drawString("AD9850 ", 20, 3);
}
if (out_mode1 == MODE_4351)
{
TFT.setTextColor(CYAN, NOIR);
TFT.drawString("ADF4351", 20, 3);
}
TFT.setFreeFont(FF1);
if (out_mode1 != memo_out_mode1)
{
if(f_mode1 == MODE_GENE) { affi_boutons_gene(); }
if(f_mode1 == MODE_WOBU) { affi_select_PAS(); }
}
memo_out_mode1 = out_mode1;
}
void efface_grand_cadre() // en épargnant la bande des boutons (1M..100k..10k..1HZ)
{
TFT.fillRect(1, 80, 317, 159, NOIR);
}
void trace_sinusoide()
{
float y;
float v;
for (uint16_t n=0; n<320; n++)
{
v = (float)n/20.0;
y = 180-50*sin(v);
TFT.drawPixel(n, (int)y, VERT);
}
}
void setup()
{
if (soft_setup == false)
{
soft_setup = true;
// étalonnage touch screen; ces valeurs peuvent varier d'un afficheur à l'autre
// pour l'instant il faut les fixer ici à la main...
eTS.x0 = -30; eTS.y0 = -30;
eTS.dx = 11; eTS.dy = 14;
Serial.begin(115200);
delay(20);
Serial.println("setup A");
pinMode(boutonPin1, INPUT_PULLUP); // bouton physique
pinMode(ADF_CLK, OUTPUT);
pinMode(ADF_DATA, OUTPUT);
pinMode(ADF_LE, OUTPUT);
pinMode(ADF_CE, OUTPUT);
pinMode(AD_WCL, OUTPUT);
pinMode(AD_D7, OUTPUT);
pinMode(AD_FQU, OUTPUT);
pinMode(AD_RESET, OUTPUT);
//pinMode(GPIO_BL, OUTPUT);
//digitalWrite(GPIO_BL, HIGH);
init_variables_globales();
Wire.begin(GPIO_SDA, GPIO_SCL, 2000000);
//Tuner_Init(tuner_init_tab9216);
//affiche_frequence(frequence);
// Start the SPI for the touch screen and init the TS library
mySpi.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS);
ts.begin(mySpi);
ts.setRotation(3);
// mySpi2 -> pour le lecteur de SDcard
// mySpi2 -> partage du bus SPI - mêmes valeurs de GPIO (sck=14, miso=12)
// que pour l'afficheur ILI9341 , sauf CS=5. Voir sur le schéma ainsi que le fichier User_Setup.h
mySpi2.begin(14, 12, 13, 5);
init_SDcard();
delay(20);
if (SDcardOk == true)
{
read_params(); // sur la SDcard
}
TFT.init();
TFT.setRotation(3); // 0..3 à voir, suivant disposition de l'afficheur
TFT.fillScreen(VERT);
init_sprites();
affi_page_info();
delay(300);
// TS_calibrate();
// si les coordonnées des points de calibrage sont aux fraises...
if ( (A.x <300) || (A.x >700) || (A.y <200) || (A.y >600) ||
(B.x < 3500) || (B.x > 3900) || (B.y <3400) || (A.y >3800) )
{
TS_calibrate();
}
out_mode1 = MODE_9850;
style = 0;
frequence = 4000000;
}
Serial.println("setup B");
init_affichages();
affi_image_from_SD("/scope2.bmp", 0, 90);
affiche_frequence(frequence); // et met à jour Fd0
delay(500);
//f_mode1 = MODE_ACCUEIL;
efface_grand_cadre(); // grand cadre en partie basse
chf_pad1.init();
CarteADF4351.init();
CarteADF4351.mute(0);
CarteAD9850.reset();
delay(10);
CarteAD9850.out_F(10000.0);
init_boutons_choix_MODE();
bt_mode_GENE.selected = true;
bt_mode_GENE.affiche(NOIR, JAUNE, 2);
f_mode1 = MODE_GENE;
bt_mode_WOBU.selected = false; // l'autre bouton
bt_mode_WOBU.affiche(NOIR, GRIS_4, 2);
affiche_frequence(frequence);
efface_grand_cadre();
affi_mode();
trace_sinusoide();
init_boutons_choix_MODULE();
/*
for(int n=0; n<21; n++)
{
uint64_t v = calcul_pas_w(n);
Serial.println(v); // pour test
}
*/
Serial.println("Fin du Setup");
Serial.println("-----------------------");
}
void get_XY_touch() // pour affi 320 x 240px
{
TS_Point p = ts.getPoint();
float dx = B.x - A.x;
float ech_x = 290.0 / dx;//300
float x0 = A.x;
float dy = B.y - A.y;
float ech_y = 210.0 / dy; //230
float y0 = A.y;
memo_x_touch = x_touch;
memo_y_touch = y_touch;
x_touch = 12 + uint16_t( (p.x - x0) * ech_x); //x_touch = 10 + uint16_t( (p.x - x0) * ech_x);
if(x_touch > 319){x_touch = 0;}
y_touch = 15 + uint16_t( (p.y - y0) * ech_y); //y_touch = 10 + uint16_t( (p.y - y0) * ech_y);
if(y_touch > 239){y_touch = 0;}
}
void test_clic_boutons(TOUCH_BOUTON *bouton_i)
{
uint16_t c1 = NOIR;
uint16_t c2 = VERT;
if ((x_touch > bouton_i->x0) && (x_touch < (bouton_i->x0 )+ bouton_i->read_dx())
&& ( y_touch > ((bouton_i->y0)) ) && (y_touch < ((bouton_i->y0) + (bouton_i->read_dy())) ) )
{
bouton_i->cliked = true;
bouton_i->selected = true;
//bouton_i->affiche(BLANC, c2, 1);
delay(100);
}
}
int test_clic_boutons_inc_dec() // boutons placés derrière les chiffres de la fréquence
{
int8_t num_bouton = -1;
uint64_t facteur;
TOUCH_BOUTON bt_Hi, bt_Li;
for(uint8_t n=0; n<10; n++)
{
bt_Hi = chf_pad1.bt_pad_H[n];
test_clic_boutons(&bt_Hi);
if(bt_Hi.cliked) { num_bouton = n; }
bt_Li = chf_pad1.bt_pad_L[n];
test_clic_boutons(&bt_Li);
if(bt_Li.cliked) { num_bouton = n+10; }
}
if(num_bouton != -1)
{
if (num_bouton<10)
{
facteur = pow(10, 9-num_bouton);
frequence += facteur;
}
if ((num_bouton>=10) && (num_bouton<20))
{
facteur = pow(10, 19-num_bouton);
if (frequence > facteur) {frequence -= facteur;}
else {frequence = 1;}
}
if (frequence == 0) {frequence = 1;}
//if (frequence > 4400000000) {frequence = 4400000000;}
if (out_mode1 == MODE_9850)
{
if (frequence < F_min_AD9850) {frequence = F_min_AD9850;}
if (frequence > F_max_AD9850) {frequence = F_max_AD9850;} // au delà le signal est possible, mais très dégradé !
}
if (out_mode1 == MODE_4351)
{
if (frequence < F_min_ADF4351) {frequence = F_min_ADF4351;}
if (frequence > F_max_ADF4351) {frequence = F_max_ADF4351;}
}
affiche_frequence(frequence);
delay(100);
}
return num_bouton;
}
void draw_AEC(uint16_t x0, uint16_t y0, uint16_t L, uint8_t sens)
{
// ligne arc-en-ciel
// affiche une ligne de pixels colorés à partir de la variable 'couleurs_aec' mémorisée en PROGMEM (voir fichier Couleurs_AEC.h)
// L = longueur de la ligne
//Serial.println("draw_draw_AEC()");
uint16_t x, i, j;
uint16_t y1;
uint16_t couleur_i;
for (int16_t i=0; i<L; i++)
{
float f = 470.0/L * i; // pour balayer toute l'échelle des couleurs disponibles
j=uint16_t(f);
couleur_i = couleurs_aec[2*j] | couleurs_aec[2*j+1]<<8;
if (sens==0){x=i;} else {x=L-i;}
TFT.drawFastVLine(x0+x, y0, 20, couleur_i);
}
}
void test_clic_bts_choix_module() // AD9850 - ADF4351
{
test_clic_boutons(&bt_AD9850);
if (bt_AD9850.cliked)
{
bt_AD9850.cliked = false;
bt_AD9850.affiche(BLANC, VERT_2, 2);
bt_ADF4351.selected = false; // l'autre bouton
bt_ADF4351.affiche(BLANC, VERT_2, 2);
out_mode1 = MODE_9850;
style = 0;
frequence = 4000000;
affiche_frequence(frequence);
affi_boutons_gene();
f_mode1 = MODE_GENE;
}
test_clic_boutons(&bt_ADF4351);
if (bt_ADF4351.cliked)
{
bt_ADF4351.cliked = false;
bt_ADF4351.affiche(BLANC, BLEU, 2);
bt_AD9850.selected = false; // l'autre bouton
bt_AD9850.affiche(BLANC, VERT_2, 2);
out_mode1 = MODE_4351;
style = 1;
frequence = 100000000;
affiche_frequence(frequence);
affi_boutons_gene();
f_mode1 = MODE_GENE;
}
}
void test_clic_bts_MODE() // GENE - WOBU
{
test_clic_boutons(&bt_mode_GENE);
if (bt_mode_GENE.cliked)
{
bt_mode_GENE.cliked = false;
bt_mode_GENE.affiche(NOIR, JAUNE, 2);
bt_mode_WOBU.selected = false; // l'autre bouton
bt_mode_WOBU.affiche(NOIR, GRIS_4, 2);
f_mode1 = MODE_GENE;
out_mode1 = MODE_9850;
style = 0;
frequence = 4000000;
affiche_frequence(frequence);
bt_mode_GENE.selected = true;
bt_mode_GENE.affiche(NOIR, JAUNE, 2);
affi_boutons_gene();
efface_grand_cadre();
init_boutons_choix_MODULE();
TFT.drawRect(0, 0, 319, 240, BLANC); // cadre principal pourtour de l'écran
bt_AD9850.selected=true;
bt_AD9850.affiche(BLANC, VERT_2, 2);
}
test_clic_boutons(&bt_mode_WOBU);
if (bt_mode_WOBU.cliked)
{
bt_mode_WOBU.cliked = false;
bt_mode_WOBU.affiche(NOIR, JAUNE, 2);
bt_mode_GENE.selected = false; // l'autre bouton
bt_mode_GENE.affiche(NOIR, GRIS_4, 2);
f_mode1 = MODE_WOBU;
num_pas = 15;
pas_W = calcul_pas_w(num_pas);
affi_select_PAS();
affi_grille();
GO();
}
}
void test_clic_bouton_RAZ()
{
test_clic_boutons(&bt_RAZ );
if (bt_RAZ.cliked)
{
bt_RAZ.affiche(BLANC, ROUGE, 1);
delay(50);
bt_RAZ.cliked = false;
bt_RAZ.selected = true;
bt_RAZ.affiche(BLANC, ROUGE, 1);
frequence =0;
affiche_frequence(frequence);
bt_RAZ.cliked = false;
bt_RAZ.selected = false;
bt_RAZ.affiche(BLANC, ROUGE, 1);
delay(300);
//init_affichages();
}
}
void deselecte_bts_preset()
{
if (out_mode1 == MODE_9850)
{
bt_455k.selected = false; bt_455k.affiche(BLANC, VERT, 1);
bt_4M.selected = false; bt_4M.affiche(BLANC, VERT, 1);
bt_10_7M.selected = false; bt_10_7M.affiche(BLANC, VERT, 1);
bt_27M.selected = false; bt_27M.affiche(BLANC, VERT, 1);
}
if (out_mode1 == MODE_4351)
{
bt_35M.selected = false; bt_35M.affiche(BLANC, VERT, 1);
bt_41M.selected = false; bt_41M.affiche(BLANC, VERT, 1);
bt_144M.selected = false; bt_144M.affiche(BLANC, VERT, 1);
bt_432M.selected = false; bt_432M.affiche(BLANC, VERT, 1);
bt_2400M.selected = false; bt_2400M.affiche(BLANC, VERT, 1);
}
}
void test_clic_bt_455k()
{
test_clic_boutons(&bt_455k);
if (bt_455k.cliked)
{
deselecte_bts_preset();
bt_455k.cliked = false;
bt_455k.selected=true;
bt_455k.affiche(BLANC, VERT, 1);
frequence =455000;
affiche_frequence(frequence);
delay(300);
}
}
void test_clic_bt_4M()
{
test_clic_boutons(&bt_4M);
if (bt_4M.cliked)
{
deselecte_bts_preset();
bt_4M.cliked = false;
bt_4M.selected=true;
bt_4M.affiche(BLANC, VERT, 1);
frequence =4000000;
affiche_frequence(frequence);
delay(300);
}
}
void test_clic_bt_10_7M()
{
test_clic_boutons(&bt_10_7M);
if (bt_10_7M.cliked)
{
deselecte_bts_preset();
bt_10_7M.cliked = false;
bt_10_7M.selected=true;
bt_10_7M.affiche(BLANC, VERT, 1);
frequence =10700000;
affiche_frequence(frequence);
delay(300);
}
}
void test_clic_bt_27M()
{
test_clic_boutons(&bt_27M);
if (bt_27M.cliked)
{
deselecte_bts_preset();
bt_27M.cliked = false;
bt_27M.selected=true;
bt_27M.affiche(BLANC, VERT, 1);
frequence =27000000;
affiche_frequence(frequence);
delay(300);
}
}
void test_clic_bt_35M()
{
test_clic_boutons(&bt_35M);
if (bt_35M.cliked)
{
deselecte_bts_preset();
bt_35M.cliked = false;
bt_35M.selected=true;
bt_35M.affiche(BLANC, VERT, 1);
frequence =35000000;
affiche_frequence(frequence);
delay(300);
}
}
void test_clic_bt_41M()
{
test_clic_boutons(&bt_41M);
if (bt_41M.cliked)
{
deselecte_bts_preset();
bt_41M.cliked = false;
bt_41M.selected=true;
bt_41M.affiche(BLANC, VERT, 1);
frequence =41000000;
affiche_frequence(frequence);
delay(300);
}
}
void test_clic_bt_144M()
{
test_clic_boutons(&bt_144M);
if (bt_144M.cliked)
{
deselecte_bts_preset();
bt_144M.cliked = false;
bt_144M.selected=true;
bt_144M.affiche(BLANC, VERT, 1);
frequence =144000000;
affiche_frequence(frequence);
delay(300);
}
}
void test_clic_bt_432M()
{
test_clic_boutons(&bt_432M);
if (bt_432M.cliked)
{
deselecte_bts_preset();
bt_432M.cliked = false;
bt_432M.selected=true;
bt_432M.affiche(BLANC, VERT, 1);
frequence =432000000;
affiche_frequence(frequence);
delay(300);
}
}
void test_clic_bt_2400M()
{
test_clic_boutons(&bt_2400M);
if (bt_2400M.cliked)
{
deselecte_bts_preset();
bt_2400M.cliked = false;
bt_2400M.selected=true;
bt_2400M.affiche(BLANC, VERT, 1);
frequence =2400000000;
affiche_frequence(frequence);
delay(200);
}
}
void affi_pasW()
{
String s1 = formatage_frq(pas_W); // ajoute les points (.) séparateurs des milliers
String s2 = supp_zeros(s1);
TFT.fillRect(130, 63, 120, 12, NOIR); // efface
TFT.setFreeFont(FF1);
TFT.setTextColor(JAUNE);
TFT.drawString("P=" + s2, 130, 63);
}
/*
void calcul_Fmin_Fmax()
{
Fmin = frequence - 160 * pas_W;
Fmax = frequence + 160 * pas_W;
}
*/
void test_clic_bt_pas_P()
{
test_clic_boutons(&bt_pas_P);
if (bt_pas_P.cliked)
{
bt_pas_P.cliked = false;
if (num_pas>0) {num_pas --;}
pas_W = calcul_pas_w(num_pas);
affi_pasW();
calcul_Fmin_Fmax(frequence);
affi_freq_W_min_max();
delay(200);
}
}
void test_clic_bt_pas_M()
{
test_clic_boutons(&bt_pas_M);
if (bt_pas_M.cliked)
{
bt_pas_M.cliked = false;
num_pas ++;
if (num_pas>20) {num_pas = 20;}
pas_W = calcul_pas_w(num_pas);
affi_pasW();
calcul_Fmin_Fmax(frequence);
affi_freq_W_min_max();
delay(300);
}
}
void affi_trace_passe_bas()
{
// (Filtre passe-bas de second ordre RLC) pour exemple...
// https://www.silicium628.fr/article_i.php?id=112
float d1, d2,d3, T;
float x = 5;
float m=0.25;
for(int n=0; n<800; n++)
{
x= n/100.0;
d1 = 1 - x*x;
d2 = 2*m*x;
d3 = d1*d1 + d2*d2;
T = 1/sqrt(d3);
uint16_t y = int(70.0 *T);
TFT.drawPixel(n, 240-y, BLEU);
}
}
String formatage_frq(uint64_t frq_i) // ajoute les points (.) séparateurs des milliers
{
String s1 = String(frq_i);
s1 = "000000000" + s1;
uint8_t L= s1.length();
String sU = s1.substring(L-3); // Hz
String sK = s1.substring(L-6, L-3); // kHz
String sM = s1.substring(L-10, L-6);// MHz
return sM + "." + sK + "." + sU + " ";
}
String supp_zeros(String s_i) // supprime les zéros et les points de séparation des milliers non significatifs
{
String s1;
while (s_i.substring(0, 1) == "0") {s_i = s_i.substring(1); }
if(s_i[0] == '.') {s_i = s_i.substring(1); }
while (s_i.substring(0, 1) == "0") {s_i = s_i.substring(1); }
if(s_i[0] == '.') {s_i = s_i.substring(1); }
while (s_i.substring(0, 1) == "0") {s_i = s_i.substring(1); }
return s_i;
}
void affi_freq_W_min_max() // et les affiche verticalement
{
// la réquence centrale est celle choisie et affichée en gros chiffres en haut
String Str_frq;
Str_frq = formatage_frq(Fmin);
TFT.fillRect(6, 150, 8, 89, NOIR); // efface
sprite_freq_W_min.drawString(Str_frq, 0, 0);
TFT.setPivot(10, 190);
sprite_freq_W_min.pushRotated(-90, NOIR);
TFT.fillRect(305, 150, 8, 89, NOIR); // efface
Str_frq = formatage_frq(Fmax);
sprite_freq_W_max.drawString(Str_frq, 0, 0);
TFT.setPivot(310, 190);
sprite_freq_W_max.pushRotated(-90, NOIR);
}
void boucle_affi_curseur()
{
// dessine un trait vertical au point cliqué par le stylet
if (pas_W==0) {return;}
if(f_mode1 != MODE_WOBU) {return;}
efface_bande_boutons();
TFT.setFreeFont(FF1);
//TFT.setTextColor(BLEU_CLAIR);
TFT.setTextColor(BLANC, NOIR);
TFT.drawString("parcourir au stylet <>", 2, 64);
init_1_bouton(1, 300, 63, 15, 16, "X", &bt_STOP_2);
bt_STOP_2.selected = true;
bt_STOP_2.affiche(BLANC, ROUGE, 2);
uint16_t memo_seg_V[100]= {0};
uint16_t memo_x;
int64_t frq_i, memo_frq_i;
TFT.setFreeFont(FM9);
TFT.setTextColor(BLEU_CLAIR, NOIR);
uint16_t couleur1 = JAUNE;
boolean stop2 = false;
while (! stop2)
{
if (ts.tirqTouched() && ts.touched())
{
memo_x = x_touch;
get_XY_touch();
if ((x_touch>15)&&(x_touch<300) && (memo_x>15) && (memo_x<300) && (y_touch > 80))
{
TFT.pushRect(memo_x, 120, 1, 100, memo_seg_V); // efface avec l'image enregistrée
TFT.readRect(x_touch, 120, 1, 100, memo_seg_V); // memorise image avant de tracer le trait
if ((x_touch>18)&&(x_touch<296)) {TFT.drawFastVLine(x_touch, 120, 100, BLEU_CLAIR);}
String s1;
memo_frq_i = frq_i;
frq_i = frequence - 160*pas_W + x_touch * pas_W;
if (frq_i != memo_frq_i)
{
if(frq_i==0) {couleur1 = ROUGE;} else couleur1 = JAUNE;
s1 = formatage_frq(frq_i) + " Hz ";
TFT.drawString(s1, 80, 82);
//delay(5);
}
}
test_clic_boutons(&bt_STOP_2 );
if (bt_STOP_2.cliked)
{
bt_STOP_2.cliked = false;
stop2 = true;
efface_bande_boutons();
}
test_bouton_physique1();
}
}
TFT.setFreeFont(FF1);
TFT.setTextColor(VERT, GRIS_6);
TFT.drawString("Choisir GENE ou WOBU" ,50, 150);
//setup();
}
void affiche_gain(float gain)
{
TFT.fillRect(175, 80, 45, 15, NOIR); // efface
TFT.setFreeFont(FF1);
TFT.setTextColor(BLEU_CLAIR);
TFT.drawString("gain=" +String(gain), 120, 80);
}
void calcul_Fmin_Fmax(uint64_t Fi)
{
if(Fi > 160*pas_W) {Fmin = Fi - 160*pas_W;} else Fmin = 0;
Fmax = Fi + 160 * pas_W;
}
void balayage_freq(uint64_t F0) // wobulation "autour" de la fréquence centrale F0
{
compte1++;
Serial.print("compte1="); Serial.println(compte1);
if ((pas_W == 0) || (f_mode1 != MODE_WOBU))
{
stop1 = true;
return;
}
uint16_t memo_seg_V[100]= {0};
int16_t memo_n;
TFT.setFreeFont(FM9);
TFT.setTextColor(BLEU_CLAIR, NOIR);
uint16_t couleur1 = JAUNE;
uint16_t valeurLue1 = 230;
uint16_t valeurLue2 = 230;
uint16_t valeurLue3 = 230;
float gain=0.3;
float memo_gain;
float vf;
uint64_t frq_i; // peut-être négatif
uint16_t v1;
uint16_t memo_v1;
uint16_t x;
TFT.setFreeFont(FF1);
TFT.drawString("gain :" +String(gain), 170, 120);
stop1 = false;
while (! stop1)
{
calcul_Fmin_Fmax(F0);
compte2++;
Serial.print("compte2="); Serial.println(compte2);
//TFT.fillRect(1, 80, 317, 159, NOIR);
//calcul_Fmin_Fcenter(F0);
TFT.setFreeFont(FF1);
TFT.setTextColor(BLANC, NOIR);
TFT.drawString("F0", 150, 220);
x=1;
for(uint16_t n=0; n<320; n++)
{
x++;
//Fmax = F0 + 160 * pas_W;
//frq_i = F0 + n * pas_W;
if(n<160){frq_i = F0 - (160-n) * pas_W;}
if(n>=160){frq_i = F0 + (n-160) * pas_W;}
frequence = frq_i;
out_frequence();
delay(1);
memo_v1 = v1;
valeurLue1 = analogRead(analogPin); //acquisition_réponse 0..4095
delay(1);
valeurLue2 = analogRead(analogPin);
delay(1);
valeurLue3 = analogRead(analogPin);
v1 = (valeurLue1 + valeurLue2 + valeurLue3)/3; // moyenne des trois acquisitions successives
vf = (float (valeurLue1) + float (valeurLue2) + float (valeurLue3))/3.0;
v1 /= 2; // 4 réglage du gain
vf *= gain; // 4 réglage du gain
//vf /=4.0;
v1 = uint16_t(vf);
if (v1 > 230-100) // écrétage de l'affichage (partie haute)
{
v1 = 230-100;
gain -= 0.01; // ajuste le gain
}
if ((x>15) && (x<300) )//&& (memo_n>15) && (memo_n<300)) à voir
{
TFT.drawFastVLine(x, 100, 131, NOIR); // efface
TFT.drawFastVLine(160, 100, 139, 10976); // trait vertical au centre (F0)
if (n%10 == 0) { TFT.drawFastVLine(n, 220, 19, 10976); }// petits traits verticaux en bas
uint16_t y1, y2;
if (polarite1 == _DIR) {y1 = 230 - memo_v1; y2 = 230 - v1;}
else {y1 = 90 + memo_v1; y2 = 90 + v1;}
if(y1 < 100) {y1=100;}
if(y2 < 100) {y2=100;}
TFT.drawLine(x-1, y1, x, y2, couleur1); // trait entre [P(n-1)] et [P(n)] ...(signal)
}
memo_n=n;
if (ts.tirqTouched() && ts.touched())
{
memo_y_touch = y_touch;
get_XY_touch();
frequence = F0; // sinon le calcul des F min et max sera faux
int num_bouton = test_clic_boutons_inc_dec(); // on peut changer la Freq centrale pendant le balayage
if (num_bouton != -1) {F0 = frequence;}
//test_clic_bts_pas(); // on peut changer le pas pendant le balayage
bt_polarite.cliked = false;
test_clic_boutons(&bt_polarite );
if (bt_polarite.cliked)
{
bt_polarite.cliked = false;
if (polarite1 == _DIR) { polarite1 = _INV; bt_polarite.label = "INV"; bt_polarite.affiche(BLANC, ROUGE, 1); }
else { polarite1 = _DIR; bt_polarite.label = "DIR"; bt_polarite.affiche(NOIR, VERT, 1); }
delay(300);
}
bt_gain_P.cliked = false;
test_clic_boutons(&bt_gain_P );
if (bt_gain_P.cliked)
{
bt_gain_P.cliked = false;
gain +=0.01;
if (gain <0.1) {gain = 0.1;}
TFT.drawString("gain=" +String(gain), 120, 80);
affiche_gain(gain);
delay(100);
}
bt_gain_M.cliked = false;
test_clic_boutons(&bt_gain_M );
if (bt_gain_M.cliked)
{
bt_gain_M.cliked = false;
gain -= 0.01;
if (gain >1.0) {gain = 1.0;}
affiche_gain(gain);
delay(100);
}
test_clic_bt_pas_P();
test_clic_bt_pas_M();
bt_STOP_1.cliked = false;
test_clic_boutons(&bt_STOP_1 );
if (bt_STOP_1.cliked)
{
bt_STOP_1.cliked = false;
bt_STOP_1.label = "";
bt_STOP_1.affiche(NOIR, NOIR, 2); // fait disparaitre le bouton de l'affichage
stop1 = true;
break;
}
}
if(gain != memo_gain) { affiche_gain(gain); memo_gain = gain;}
test_bouton_physique1();
}
}
frequence = F0;
}
void GO()
{
//if (pas_W == 0) {return;}
bt_STOP_1.label = "X";
bt_STOP_1.affiche(BLANC, ROUGE, 2);
delay(100); // évite de redéclencher le bouton intempestivement
TFT.fillRect(6, 82, 150, 10, NOIR); // efface le texte "Choisir un pas"
affi_freq_W_min_max(); // affiche verticalement
balayage_freq(frequence); // wobulation "autour" de la fréquence centrale F0
}
void affi_grille()
{
efface_grand_cadre();
TFT.drawFastVLine(160, 100, 139, 10976);
for (int n =1; n<32; n++)
{
TFT.drawFastVLine(10*n, 220, 19, 10976);
}
TFT.drawFastHLine(1, 231, 318, GRIS_6); // zero en bas
TFT.drawFastHLine(1, 98, 318, GRIS_6); // max en haut
init_1_bouton(1, 300, 82, 15, 15, "X", &bt_STOP_1);
bt_STOP_1.selected = true;
bt_STOP_1.affiche(BLANC, ROUGE, 2);
init_1_bouton(1, 230, 82, 30, 15, "DIR", &bt_polarite);
bt_polarite.selected = true;
bt_polarite.affiche(NOIR, VERT, 1);
init_1_bouton(1, 300, 100, 15, 15, "+", &bt_gain_P);
bt_gain_P.selected = true;
bt_gain_P.affiche(NOIR, BLEU_CLAIR, 1);
init_1_bouton(1, 300, 120, 15, 15, "-", &bt_gain_M);
bt_gain_M.selected = true;
bt_gain_M.affiche(NOIR, BLEU_CLAIR, 1);
/*
if(le_pas_est_choisi == false)
{
TFT.setFreeFont(FF1);
TFT.setTextColor(BLANC, ROUGE);
TFT.drawString("Choisir un pas", 80, 150);
}
*/
}
void test_clic_bouton_TEST()
{
test_clic_boutons(&bt_TEST );
if (bt_TEST.cliked)
{
bt_TEST.affiche(BLANC, ROUGE, 1);
delay(10);
Serial.println("-------------------------------");
Serial.println("bt_TEST.cliked");
bt_TEST.cliked = false;
bt_TEST.selected = true;
bt_TEST.affiche(BLANC, ROUGE, 1);
//affi_nuances_de_gris();
TS_calibrate();
//TFT.fillScreen(NOIR); // effface
//draw_AEC(0, 100, 320, 1);
//delay(300);
bt_TEST.cliked = false;
bt_TEST.selected = false;
bt_TEST.affiche(BLANC, ROUGE, 1);
//init_affichages();
//affiche_frequence(frequence);
//affiche_frequence(1);
}
}
double nb=0;
void test_clic_bts_preset()
{
if(f_mode1 == MODE_WOBU) {return;}
if (out_mode1 == MODE_9850)
{
test_clic_bt_455k();
test_clic_bt_4M();
test_clic_bt_10_7M();
test_clic_bt_27M();
}
if(out_mode1 == MODE_4351)
{
test_clic_bt_35M();
test_clic_bt_41M();
test_clic_bt_144M();
test_clic_bt_432M();
test_clic_bt_2400M();
}
}
void loop()
{
if (ts.tirqTouched() && ts.touched())
{
memo_y_touch = y_touch;
get_XY_touch();
test_clic_boutons_inc_dec();
test_clic_bouton_RAZ();
if((f_mode1 == MODE_ACCUEIL) || (f_mode1 == MODE_GENE))
{
test_clic_bts_choix_module();
}
if(f_mode1 == MODE_GENE) { test_clic_bts_preset(); }
if(f_mode1 == MODE_WOBU)
{
test_clic_bt_pas_M();
test_clic_bt_pas_P();
}
//if(f_mode1 == MODE_WOBU) { test_clic_bts_pas(); }
test_clic_bts_MODE();
if(stop1 == true)
{
stop1= false;
boucle_affi_curseur();
}
}
test_bouton_physique1();
delay(20); //20
// uint16_t valeurLue1 = analogRead(analogPin);
// frequence = valeurLue1;
// //Serial.println(valeurLue1);
// affiche_frequence(frequence);
}
/** ***************************************************************************************
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()
{
}
void TOUCH_BOUTON::init(uint16_t x_i, uint16_t y_i, uint8_t dx_i, uint8_t dy_i, uint8_t dr_i, uint16_t couleur_i)
{
x0 = x_i;
y0 = y_i;
dx = dx_i;
dy = dy_i;
dr = dr_i;
couleur = couleur_i;
cliked = false;
selected = false;
}
void TOUCH_BOUTON::affiche(uint16_t coul_txt, uint16_t coul_fill_select, uint8_t n_font)
{
uint16_t couleur_contour = GRIS_5;
TFT.setTextColor(coul_txt);
if(selected)
{
TFT.fillRoundRect(x0, y0, dx, dy, dr, coul_fill_select);
}
else
{
TFT.fillRoundRect(x0, y0, dx, dy, dr, couleur); // efface
TFT.drawRoundRect(x0, y0, dx, dy, dr, couleur_contour); // retrace juste le contour
}
//FM9 FMB9 FSS9... voir le fichier FrSD_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(label, x0+3, y0 - (2*n_font) + (dy-4)/2);
}
uint8_t TOUCH_BOUTON::read_dx()
{
return dx;
}
uint8_t TOUCH_BOUTON::read_dy()
{
return dy;
}
/** ***************************************************************************************
CLASS CHF_PAD // boutons invisibles pour incrémenter/décrémenter les chiffres de la fréquence
********************************************************************************************/
// Constructeur
CHF_PAD::CHF_PAD()
{
}
void CHF_PAD::init()
{
for(uint8_t n=0; n<=9; n++) // 1 9
{
bt_pad_H[n].init(x_ch[n], 16, 25, 22, 3, GRIS_3); //18
//bt_pad_H[n].affiche(BLANC, VERT, 1); // pour visualiser la position des boutons
bt_pad_L[n].init(x_ch[n], 38, 25, 22, 3, GRIS_3); //40
//bt_pad_L[n].affiche(BLANC, ROUGE, 1);
}
}