Eclairage à led de vélo 3W+tracker (atmega, ESP32)

J’ai essayé votre programme sur un ESP32 TTGO avec un oled couleur d'aliexpress Mais j’ai un souci car je n’arrive pas à afficher quelques choses sur le oled pourtant j’ai bien télécharge les bibliothèques comme expliqué ici, ainsi que d’inclure les chemins ou sont les bibliothèques et le driver. cela compile bien https://github.com/Xinyuan-LilyGO/TTGO-T-Display https://www.instructables.com/Select-Color-Display-for-ESP32/

La variable i s’incrémente bien sur le moniteur série donc l’ESP32 fonctionne Pourriez-vous m’eclairer, SVP, car je suis dans le brouillard

Je mets le minimum du programme pour faire fonctionner le oled ici

#include 
#include 
//#include "WiFi.h"
#include 
//#include 
#include "esp_adc_cal.h"

#include 
//#include 
//#include  


//#include  
//#include 


//#define ST7789_DRIVER
//#define ILI9341_DRIVER

//#define CGRAM_OFFSET      // Library will add offsets required


//#define TFT_MOSI            19    //SDA
//#define TFT_SCLK            18    //SCL
//#define TFT_CS              5     //CS
//#define TFT_DC              16    //RS
//#define TFT_RST             23    //reset

//#define TFT_BL          4  // Display backlight control pin

#define TFT_BACKLIGHT_ON HIGH  // HIGH or LOW light OLED or not



//#define TFT_WIDTH  135
//#define TFT_HEIGHT 240
TFT_eSPI tft = TFT_eSPI (TFT_WIDTH, TFT_HEIGHT);  // édité



/*
#define LOAD_GLCD
#define LOAD_FONT2
#define LOAD_FONT4
#define LOAD_FONT6
#define LOAD_FONT7
#define LOAD_FONT8
#define LOAD_GFXFF

#define SMOOTH_FONT
*/


//#define SPI_FREQUENCY  27000000
//#define SPI_FREQUENCY    40000000   // Maximum for ILI9341


//#define SPI_READ_FREQUENCY  6000000 // 6 MHz is the maximum SPI read speed for the ST7789V

char buff[512];
int vref = 1100;
int i;

#define ADC_PIN 34

void setup()
{
  
Serial.begin(115200);

pinMode(2, OUTPUT);   //led
//pinMode(34, INPUT);   //led

tft.init();
tft.setRotation(1);
tft.fillScreen(TFT_BLACK);
tft.setTextSize(2);
tft.setTextColor(TFT_WHITE);
tft.setCursor(0, 0);
tft.setTextDatum(MC_DATUM);


if (TFT_BL > 0) { // TFT_BL has been set in the TFT_eSPI library in the User Setup file TTGO_T_Display.h
         pinMode(TFT_BL, OUTPUT); // Set backlight pin to output mode
         digitalWrite(TFT_BL, TFT_BACKLIGHT_ON); // Turn backlight on. TFT_BACKLIGHT_ON has been set in the TFT_eSPI library in the User Setup file TTGO_T_Display.h
    }
    

tft.setTextSize(1);
uint16_t v = analogRead(ADC_PIN);
float battery_voltage = ((float)v / 4095.0) * 2.0 * 3.3 * (vref / 1000.0);
String voltage = "Voltage :" + String(battery_voltage) + "V";
Serial.println(voltage);
tft.fillScreen(TFT_BLACK);
tft.setTextDatum(MC_DATUM);
tft.drawString(voltage, tft.width() / 2, tft.height() / 2 );
delay(1000);
tft.drawString("Press again to wake up", tft.width() / 2, tft.height() / 2 );
delay(1000);

     tft.fillRect(0,0,240,135, TFT_BLUE); // erase the screen display
     tft.setTextSize(3);   // (num colonne , num ligne)
     tft.setCursor(0, 35); // (x colonne , y ligne) - F6CZV
     tft.print("VFO"); // F6CZV
delay(1000);

}




void loop()
{
  i++;
  if ( digitalRead(2)== 1 ) {digitalWrite(2,LOW);}  else {digitalWrite(2,HIGH);}
  Serial.println(i);
//tft.setRotation(0);

tft.fillScreen(TFT_RED);
delay(1000);
tft.fillScreen(TFT_BLUE);
//espDelay(1000);
delay(1000);
tft.fillScreen(TFT_GREEN);
delay(1000);
}

il y a une instrumentation de velo sur ce forum ici, j’ai envoyé un mail mais sans reponse http://cyclurba.fr/forum/570020/dn-codage-protocole-sn-rie-bbs0x.html?from=571&discussionID=18542&messageID=638753&rubriqueID=102&pageprec

Ca peut venir du fait que le constructeur

TFT_eSPI tft = TFT_eSPI(135, 240); // Invoke custom library

est avant les define des pins du SPI.

J'utilise ce même module TTGO et ça fonctionne bien. Il faut sélectionner

#define ILI9341_DRIVER

dans le fichier User_Setup.h de la bibliothèque TFT_eSPI. Les autres lignes doivent commentées :

// Only define one driver, the other ones must be commented out
#define ILI9341_DRIVER
//#define ST7735_DRIVER      // Define additional parameters below for this display
//#define ILI9163_DRIVER     // Define additional parameters below for this display
//#define S6D02A1_DRIVER
//#define RPI_ILI9486_DRIVER // 20MHz maximum SPI
//#define HX8357D_DRIVER
//#define ILI9481_DRIVER
//#define ILI9486_DRIVER
//#define ILI9488_DRIVER     // WARNING: Do not connect ILI9488 display SDO to MISO if other devices share the SPI bus (TFT SDO does NOT tristate when CS is high)
//#define ST7789_DRIVER      // Full configuration option, define additional parameters below for this display
//#define ST7789_2_DRIVER    // Minimal configuration option, define additional parameters below for this display
//#define R61581_DRIVER
//#define RM68140_DRIVER
//#define ST7796_DRIVER
//#define SSD1963_480_DRIVER    // Untested
//#define SSD1963_800_DRIVER    // Untested
//#define SSD1963_800ALT_DRIVER // Untested
1 Like

A partir d’un d’éclairage arrière chinois à 5€, un Arduino pro mini a été programmé pour optimiser les performances de l’éclairage de la LED en mode flash et d’optimiser l’autonomie. En effet, un capteur de luminosité permet de faire d’augmenter l’éclairage de la led lorsque la luminosité extérieure est importante pour être bien vu de jour, mais aussi par temps de brouillard. C’est éclairage est devenu le plus performant de ce qui existe sur la marché. https://www.fub.fr/tests-eclairages Mais, il est possible de paramétrer l’éclairage par Bluetooth comme on peut le voir sur la photo suivante |500x375 En PDF, la méthodologie et le programme pour optimiser l’éclairage et les choix effectués ainsi que le programme….. https://www.fichier-pdf.fr/2021/01/31/rear-light-bike-3w-arduino-nano-bluetooth-mpu6050-v1/

D’autres prototypes devraient voir le jour avec amélioration et la minimisation du volume de l’électronique et du boitier.

1 Like

Suite au PDF précèdent,

Pour minimiser le câblage et éviter le problème du téléchargement d’un nouveau sketch de devoir déconnecter le HC06 à cause qu’il transmet tout le temps

J’ai voulu remplacé le HC06 par le BLE NAN0
Mais, je suis très déçu du BLE keywish qui ne se gère pas du tout comme un HC06
le manuel est tres bien fait
[keywish-nano-plus/Ble-Nano operation manual V.1.6.pdf at master · keywish/keywish-nano-plus · GitHub](http://“https://github.com/keywish/keywish-nano-plus/blob/master/BLE-Nano/Ble-Nano operation manual V.1.6.pdf”)

Par contre, il faut utiliser leurs applications
BLETestToosV1.0.apk

Mais qui est en mandarin, j’arrive quand même à commander l’éclairage et lire les valeurs du bluetooth….mais plus possible d’utiliser l’application bluetoothelectronics
https://www.keuwl.com/apps/bluetoothelectronics/
J’ai essayé de modifier le paramétrage avec la commande AT, le BLE NANO mais sans succès
j’ai envoyé un mail au support keywish, sans reponse depuis 1 semaine

La consommation moyenne du BLE nano est de 6mA avec un envoie 33 caracteres tous les 0.1s

On a modifié le programme de test du courant pour voir une commande continu et de modifier la periode lors de test de nouvelle LED

exemple, on a rajouté 3 led de petite puissance pour etre vu sur le coté
L’éclairage sur le côté ne demande pas d’être vu à 150m, sachant que lorsque l’on a un éclairage de de 10Watt à l’avant son flux est visible de côté ainsi que la réflexion de l’éclairage sur le sol
Pour être vu de coté à 6m avec 0.7 lux sur une largeur de 2m, il faut un angle d’environ de 6°
Avec 1 lumen ou 14 candela comme le démontre les équations suivantes

Par conséquent, de petite leds faibles puissance (50mA). seront suffisantes de diametre 5mm.
(3 led seront utilisé, 2 sur le coté et une pour l’arriere).

2 solutions pour faire la commande des 3 leds (3*50mA).

  • soit utiliser une résistance de limitation de courant qui aura des pertes mais sera une commande très fiable.
  • soit utiliser un hacheur qui minimisera les pertes mais si la régulation de courant n’est pas correcte alors il y a un risque de destruction des led et du transistor de commande. Pour ce courant pas la peine de prendre un transistor super-dimensionné avec un boitier TO251 mais un petit boitier SOT23 suffira
    L’inductance sera aussi bien plus petite devant supporte seulement un courant 150mA.

exemple de choix de led __*C503B-RAS *__6° 50mA 15 candela.
en mode eclairement continu, on peut mesurer les lux à 50cm sur un mur

Toujours à 50cm l’éclairage en fonction du courant est bien correct autour de 50mA avec un coefficient de performance de 3200lux/A
Puis, au-delà de 0.1A, les performances de l’éclairage se dégradent fortement.

Voici la commande des 3 led avec hacheur en boucle ouverte et de la led de puissance en simulation

le programme de test des leds en mode continu et pediodique en piece jointe

MPU6050_nano_blue_v1.ino (6 KB)

Pour mesurer le courant et faire une boucle fermée de la régulation de courant, des transistors canal P sont utilisés. De plus, avec une tension d’alimentation de 3 à 4.2 V il n’y a plus besoin de mettre le transistor NPN pour driver le transistor canal P comme sur le schéma datant du 31 Janvier 2021.

L’Arduino NANO a été remplacé par un Arduino Pro mini car ce dernier consomme beaucoup moins d'énergie.

Le capteur de température sera retiré car la LED de puissance en mode flash aura un incrément de température faible de 2°C par rapport à la température ambiante, une fois que le rapport cyclique sera de 1/20 (temps allumé de 0.05s sur une période de 1s.

Voici le nouveau schéma électrique de simulation qui nous a permis de valider le fonctionnement global avec le transistor canal P :

|500x303

La boucle fermée de régulation numerique a été simulé sous Simulink, voici le résultat obtenu pour une consigne de 1A.

|500x108

Etant donné que le temps d'echantillon et faible par rapport à la constante de temps de la regulation, la fonction de transfert en laplace va etre determiner pour faire un choix de ki |459x500

A partir de la fonction de transfert precedente, la constante de temps de la régulation de courant correspond à l’équation suivante

Sur cette figure suivante de matlab, on voit que l’erreur statique du courant est nulle et que le temps de réponse est de 0.03s, grâce au correcteur Intégral ayant un ki=10. De meme, on peut observer que le courant est nul pendant 0.01s, cela correspond au temps pour que la tension du hacheur soit supérieure à la tension de seuil de la LED.

|500x356

Il faut tester les transistors MOS en réel pour vérifier que cela fonctionne malgré la variation de la tension dans la batterie.

1 Like

Une autre façon de travailler avec le transistor canal N tout en faisant la régulation du courant a été trouvée.

Voici la façon dont la solution a été trouvée :

Tout d’abord il a été ajouté sur le schéma datant du 31 janvier, une résistance de 1ohm à la source du transistor canal N car cela permet de mesurer une tension qui est l’image du courant, par exemple : s’il y a un courant de 1A à la source du transistor, la tension vaut : R*I=1*1=1V.

Voici le schéma :

|500x489

Résultat obtenu en simulation

Sur cette figure on voit bien que le courant mesuré ne correspond pas au courant souhaité car lorsque le transistor est bloqué le courant mesuré vaut 0 et lorsqu’il est passant on ne maîtrise pas la valeur mesurée.

|500x323

Afin de résoudre ce problème il a été ajouté un condensateur à la source du transistor de façon à avoir un montage RC à la source du transistor. Avec ce montage en jouant sur la constante de temps R.C il sera possible de mesurer le vrai courant sur la LED.

La valeur du condensateur a été calculée de la façon suivante comme pour un filtre du premier ordre qui donnera la valeur moyenne de la mesure du courant

De façon à ne plus voir les instants auxquels le transistor est soit bloqué ou soit passant, il faut que la constante de temps soit très supérieure à la période d’hachage.

La période d’hachage vaut 1/Freqhachage=1/64kHz=0.0000156S, donc il faut une constante de temps très supérieure à 0.0000156S.

La constante de temps vaut t=R*C, si C=47uF, R*C=1*47=0.0000047S, ce qui est très supérieure à la période d’hachage. Donc on prend une valeur de 47uF pour le condensateur.

Voici le schéma

|500x489

Résultat obtenu en simulation :

On voit bien que maintenant le courant mesuré correspond au courant moyen du transitor avec un regime continu, donc les mesures effectuées à l’aide de l’Arduino seront cohérentes et grâce à cela il sera possible de faire la régulation du courant.

le courant dans la LED correspond à l’equation suivante I led=Imoyen transitor*255/PWM decimale

|500x332

Voici le schéma complet qui nous a permis de valider notre régulation avec le transistor canal N :

|500x346

1 Like

Suite à la réalisation du montage sur ISIS, il a été effectué différents tests tels que :

L'évolution du courant en fonction du rapport cyclique généré par la PWM grace à l'asservissement de courant avec une consigne de 1A. L Le temps de reponse est bien de 0.3s de la regulation, avec un coefficient integral de 10

Un programme qui envoies les données( Intensité du courant et rapport cyclique ) sur le terminal virtuel (UART ou USART) a été fait afin de pouvoir extraire et visualiser correctement l'allure du courant grâce au logiciel Excel. Sur l'image ci-dessous il y'a un terminal virtuel contenant les données qui seront utilisées pour tracer la courbe.

|500x346

Voici les données du terminal en fonction traiter dans Excel des mesures de la simulation. On peut observer que le courant est moyennement filtré ce qui provoque de légère ondulation autour de la consigne à la période d’échantillonnage de 0.1s ce qui provoque aussi des variations faibles de la sortie de régulation PWM.

|500x290

On retrouve bien le temps de 0.4s pour atteindre la consigne, comme dans Matlab Etant donné que la période d’échantillonnage est faible, la réponse échantillonnée est similaire à celle en continu.

voici le programme de l'asservissement

#include 
#include      //https://www.arduino.cc/en/Reference/SoftwareSerialBegin
#include 
#include        //chien de garde
//#include    //mise en veille
//#include 
#include "LowPower.h"     //https://github.com/rocketscream/Low-Power




#define BP3        2       // 
#define battery    A0      //relay magnetron



LiquidCrystal lcd(9, 8, 4, 10, 11, 7);   // LiquidCrystal lcd(rs, en, d4, d10, d11, d7);
// Configuration des variables


unsigned int temps=0, PWM2;    //temps de la routine d'interruption
byte  temps1=0,mode=1,PWM=255,Integralbyte;   
float I=0,Iled,erreur=0,kp=10,ki=10,Ic=1,Integral=150;



// the setup function runs once when you press reset or power the board
void setup() {
   pinMode(5, OUTPUT);      //PWM
   pinMode(6, OUTPUT);      //PWM


   Timer1.initialize(1000);           // initialize timer1, and set a 0,1 second period =>  100 000  pour 0.01s  10 000
   Timer1.attachInterrupt(callback);   // attaches callback() as a timer overflow interrupt
   lcd.begin(16, 2);                   //modifier pour un afficheur 20x4


   TCCR0B = (TCCR0B & 0b11111000) | 0x01;         //pin 5  64khz    http://playground.arduino.cc/Main/TimerPWMCheatsheet
                                            
   pinMode(A5, OUTPUT);
   pinMode(2, INPUT);
   analogWrite(5,255);
   attachInterrupt(digitalPinToInterrupt(2), interBP, LOW);   //routine d'interruption exterieur broche 2
   
   analogReference(INTERNAL);

  
}



// Interruptions  tous les 0.1s fait par le timer1***********************************
void callback()  {
 temps++;


}


//interruption exterieur front descendant de la broche 2
void interBP() {
//interrupts();
  mode++;                  //incrementation des modes 
  if (mode>3) mode=1; 

  switch (mode) {
  case 1:Ic=1;Integral=180;   break;   //donne un ordre de grandeur de la valeur de la PWM=255*(Rshunt*Ic-Useuil)/Ubattery
  case 2:Ic=0.75;Integral=240;   break;
  case 3:Ic=1.5;Integral=250;   break;
     }
   } 

   
void loop() {  
   SoftwareSerial serial(0,1);
   serial.begin(9600);
         
  if (temps>1)         //affichage tous les 100ms
  {
      // Lecture de la tension*2=courant car ll y a une resistence de mesure de 0.5ohm
      I=analogRead(A1);
      I=I*0.00215;     //I*1.1/(1024*0.5ohms)  i moyen transistor      
      Iled=(I*255)/PWM;
 erreur=Ic-Iled;

      lcd.setCursor(0,0); lcd.print(Ic);
      lcd.setCursor(0,1);lcd.print("Er=");lcd.print(erreur,1);
      lcd.setCursor(8,1);lcd.print("I=");lcd.print(I);
      


      //Correcteur PI; PWM=ki*Erreur/P********************************************************
      Integral= Integral+erreur*ki; 
      if (Integral>=255) Integral=255;
      if (Integral<=0) {Integral=0;}
      Integralbyte=Integral;
      
      PWM=Integralbyte;// Rapport cyclique inversé car le transistor est un Canal P
                        // Rapport cyclique entre 255(100%) et 0 (0%)
      serial.print(I); serial.print(";");    //
      serial.print(PWM2); serial.println(";");                 
      
      analogWrite(5,PWM);    //commande de la LED de puissance
    
      lcd.setCursor(8,0);
      PWM2=(Integralbyte*100)/255;
      lcd.print("PWM=");
      lcd.print(PWM2);
      lcd.print("%  ");
      
      temps=0;
}

   
} // fin loop

Les résultats obtenus sont corrects car la courbe possède les mêmes caractéristiques obtenu sur le logiciel MATLAB.

2 Likes

Suite à la commande en boucle ouverte des 3 leds de ce post du feb 09 2021 des tests on été fait pour ajuster la Commande PWM pour avoir le bon courant. En effet, l'inductance a été changé.

L'étude de ces leds est sur le lien suivant post sur du Mardi 16 Février sur le forum Vélorizontal, les graphes et équations pour la commande en PWM des LED 10mA à 120mA.

|500x291

La commande est faite en référence à la courbe ci-dessous : |500x309 On incrémente la PWM petit à petit en mode continu d'éclairage pour connaitre le courant pour une tension de batterie de 4.2V

|500x309

Mais la courbe précédente n'est pas très utile car l'on désire un courant constant de 10mA. par conséquent, c'est la courbe suivante pour connaitre la PWM en fonction de la variation de la tension batterie.

|500x309 A partir de la courbe précédente, voici l’équation permettant de contrôler le courant des diodes : PWM = (14*Iconsigne+1)*225/Vbatt.

Et voilà le programme de l'Arduino qui gère la led de puissance et les leds auxiliaires

#include  
#include    
#include 

float IconsigneP=0.1;
float IconsigneAux = 0.01;
float Imax=0;
float Res=0.22;   //resistance
float Tension=4.2;
float pourcetage;
float outregul1;

float T_3=4.2;
float T_2=4.2;
float T_1=4.2;     

float TF3;
float TF2;
float TF1;
float TF;
float TensionF;


int16_t temperat;
bool flagmesure=0;

uint8_t  counter=0;
int8_t  counter13=0;
int8_t  periode13=0;
uint8_t  counteraffichage=0;
uint8_t out=0;
uint8_t outregul=70;
uint8_t outregul2=70;
uint8_t out2=0;

uint8_t  timer=0;
uint8_t  heure;
uint8_t minuTe;   //déclaration minute
uint8_t seconde;  //déclaration seconde


float IconsigneMaxP = 0.7;
float IconsigneMinP = 0.1;

float IconsigneMaxAux = 0.12;
float IconsigneMinAux = 0.01;

uint8_t  mode=0;

char BluetoothData;
char BluetoothData2;

//SoftwareSerial BT(0, 1);   // RX, TX mais il n'y a pas trop le choix sur la nano //pas nécessaire de définir un objet serial sur l'UART existant


/*   https://docs.rs-online.com/c150/0900766b81414edd.pdf      registre datashhet mpu6050
     https://docs.rs-online.com/e2e2/0900766b81414ed9.pdf     specificiation
*/
void setup() {
pinMode(13, OUTPUT);    //test le temps de programme  //initilisable par le PCB
pinMode(12, OUTPUT);    //test le temps du flash      //initilisable par le PCB
//pinMode(3, OUTPUT);   //PWM 3 timer2  32KHz hachage //initilisable par le PCB
pinMode(5, OUTPUT);     //PWM 5 timer0  64KHz hachage

pinMode(6,OUTPUT);      //PWM LED auxiliaires
pinMode (3, INPUT_PULLUP);   //inutilisable par le PCB
pinMode (4, INPUT_PULLUP);   //inutilisable par le PCB
//pinMode(7, INPUT);         //inutilisable par le PCB

  Timer1.initialize(50000);           // initialize timer1, and set a 0,1 second period =>  100 000  pour 0.01s  10 000
  Timer1.attachInterrupt(callback);   // attaches callback() as a timer overflow interrupt

// TCCR2B = (TCCR2B & 0b11111000) | 0x01;       //pin 3  32khz    http://playground.arduino.cc/Main/TimerPWMCheatsheet
TCCR0B = (TCCR0B & 0b11111000) | 0x01;          //pin 5  64khz 

analogReference(INTERNAL) ;   //1.1V tension de refenrence inernal
//analogReference(DEFAULT) ;  // ne peut être utilisé étant donné que la tension d'alimentation est inférieure à 5 V et variable

outregul=100;   //mettre la PWM

minuTe=EEPROM.read(0);                //minute de fonctionnement de l'eclairage
heure = EEPROM.read(2);               //heure
if (minuTe==255)  {EEPROM.put(0, 0);}   //la premier fois FF donc ecriture à 0 minute et heure
if (heure==255)   {EEPROM.put(2, 0);}

mode=EEPROM.read(3);      //changement de mode
mode++;
if (mode==1) {IconsigneP=0.7;periode13=3;}
if (mode==2) {IconsigneP=0.5;periode13=10;} 
if (mode>=3) {IconsigneP=0.2;mode=0;periode13=19;}
EEPROM.put(3, mode);

//BT.begin(9600);
Serial.begin(38400);
}


// Interruptions  tous les 0.05s fait par le timer1***********************************
void callback()  {

//utilité à vérifier, car le pin 13 est lié à rien !!!
counter++;      //fonctionnement mode flash
if (counter<=1)  {out=outregul;digitalWrite(12,HIGH);}           //temps de 50ms, 
if (counter>=2)  {out=0;digitalWrite(12,LOW);}
if (counter>=19)  {counter=0;}            //temps de 1s                                                             

out2 = 200;
analogWrite(6,out);   //PWM 64kHz LED principale
analogWrite(5,outregul2);   //PWM LED auxiliaires en fonctionnement continu

//utilité à vérifier, car le pin 13 est lié à rien !!!
counter13++;      //fonctionnement mode flash
if (counter13<=1)  {digitalWrite(13,HIGH);}          //temps de 50ms, 
if (counter13>=2)  {digitalWrite(13,LOW);}
if (counter13>=periode13)  {counter13=0;}            //periode variable  


counteraffichage++;
if (counteraffichage>=4)  {flagmesure=1;counteraffichage=0; }  //perdiode d'affichage 0.2s       2

timer++;
if (timer>=19 && Tension>3.1)  {    
      seconde++;timer=0;        //etude temps de fonctionnement                                             
      if(seconde >= 60){seconde =0;  minuTe++; EEPROM.put(0, minuTe);        //EEPROM.write(address, value)
          if(minuTe >= 60){ minuTe =0;  heure++;EEPROM.put(2, heure);    }   } } //pas grave que 24h soit depassé
                                
}//fin callback


//**********************************
void loop() {



if (flagmesure==1)   {
//digitalWrite(13,HIGH);                 //duree 20ms
Tension=analogRead(A7);   //10bit
Tension=(Tension*1.1*4.21)/1024;                //4.21 correspond au pont diviseur

T_3=T_2;
T_2=T_1;      //recurence n-2
T_1=Tension;  //recurence n-1

TF3=TF2;
TF2=TF1;
TF1=TF;

TF=Tension+3*T_1+3*T_2+3*T_3+0.278059*TF3-1.18289*TF2+1.76*TF1;   
//filtre numerique passe bas Fc=0.5s 3eme ordre  de la mesure de la tension fe=5Hz  periode0.2s
TensionF=TF/69;        //55 en theorie

pourcetage=83*TensionF-250;                       //a=(100-0)/(4.2-3)=83.33   b=-250


if (TensionF>=3.5) {
  outregul1 = (((1.6*IconsigneP+1.9)/TensionF)*255);     //mettre la PWM
  outregul2 = (((14*IconsigneAux+1)/TensionF)*255);     //PWM LED auxiliaires 
  if (outregul1>255) {outregul1=255;} 
  if (outregul1<70) {outregul1=70;}
  
  if (outregul2>255) {outregul2=255;} 
  if (outregul2<70)  {outregul2=70;}   
  
  outregul=outregul1;}
if (TensionF<3.5) {IconsigneP=0.3;}
if (TensionF<=3.1) {outregul=0;}  

//envoie des données en bluetooth
Serial.print("*O"+String(outregul)+"*");  
Serial.print("*F"+String(outregul2)+"*");
Serial.print("*P"+String(pourcetage)+"*");
Serial.print("*T"+String(TensionF,2)+"*");
Serial.print("*I"+String(IconsigneP,1)+"*");
Serial.print("*R"+String(IconsigneAux,2)+"*");
Serial.print("*m"+String(minuTe)+"*");
Serial.print("*h"+String(heure)+"*");
Serial.println();
//Serial.print("test"); //debug
flagmesure=0;
//digitalWrite(13,LOW);     
}


if (Serial.available()){
  BluetoothData = Serial.read();        //Get next character from bluetooth


if (BluetoothData == 'A') IconsigneP = IconsigneP + 0.1;
if (BluetoothData == 'B') IconsigneP = IconsigneP - 0.1;

if (BluetoothData == 'a')IconsigneAux = IconsigneAux + 0.01;
if (BluetoothData == 'b')IconsigneAux = IconsigneAux - 0.01;


if(BluetoothData == 'H' or BluetoothData2 == 'H') {seconde = 0;minuTe = 0;heure = 0;}      //remise à zero
BluetoothData = 0; 
  }

if(IconsigneP > IconsigneMaxP) IconsigneP = IconsigneMaxP; 
if(IconsigneP < IconsigneMinP) IconsigneP = IconsigneMinP;

if(IconsigneAux > IconsigneMaxAux) IconsigneAux = IconsigneMaxAux; 
if(IconsigneAux < IconsigneMinAux) IconsigneAux = IconsigneMinAux;  


}//fin loop
2 Likes

Etude d’une LED 65cd 50mA, 8° vendu par farnell. Ci-dessous vous trouverez le Lien de farnell avec la datasheet de la LED. farnell : https://fr.farnell.com/vishay/vlcs5830/led-aec-q101-5mm-rouge-65cd-624nm/dp/2889660?ost=2889660 Datasheet : https://4donline.ihs.com/images/VipMasterIC/IC/VISH/VISHS87555/VISHS87555-1.pdf?hkey=6D3A4C79FDBF58556ACFDE234799DDF0

La Jonction de la LED peut supporter une température de 92°C comme nous pouvons voir sur le calcul ci-dessous : T° jonction =T° Ambiant+RTHja*Power=20°C+300*(2.4V*0.1A)= 92°C

Ci-dessous les photos de son éclairage à 40cm. On peut observer que l’intensité lumineuse est légèrement plus faible au centre que sur les côtés. Le demi angle correspond bien au donnée constructeur de Atan(rayon eclairage/distance) =Atan(4cm/40cm)=5.7°

|409x500

|500x225

D’ailleurs, sur la courbe suivante, on peut observer les lux en fonction du rayon.

|500x407

Pour avoir le lumen total nous avons utiliser la relation suivante ( L2+L3*8 )0,02*0,02 (qui correspond à la somme (du lux à la surface 0 et du demi côté de 0 à 4cm) 8 (correspond aux 8 points du capteur)*la surface du capteur)

Voici l’intensité lumineuse à 40cm en fonction du courant On peut observer que l’intensité est maximum à 0.2A.

|500x244

2 Likes

Ci-dessous vous trouverez l’image 3D du PCB et le lien pour télécharger les fichiers ISIS du schéma électrique ainsi que le typon(PCB) : TR ECLAIRAGE - Google Drive

Voici quelques mesures de courant en pratique.

Graphique pour C=220uF
Grâce au comportement du condensateur, le courant n’arrive pas à 0, en revanche le courant n’est pas en régime continu.

Graphique pour (C1+C2=440uF)

Il est maintenant remarquable qu’avec une constante de temps qui est deux fois plus grande que celle du graphique antérieur, le courant en fonction du temps se rapproche du régime continu.

3 Likes

Il n’y a pas qu’une seule solution pour réaliser un éclairage vélo……et pour faire sa commande, il va falloir faire une synthèse dans des dossiers

D’ailleurs, voici encore une nouvelle solution avec un TTGO+OLED Pour que le OLED du TTGO, il faut prendre la bibliothèque tft espI sur ce lien et pas ailleurs, sinon cela ne fonctionne pas https://github.com/Xinyuan-LilyGO/TTGO-T-Display Lorsque la bibliothèque est installée, il y a de nombreux exemple que l’on retrouve dans le compilateur IDE Arduino [](https://servimg.com/view/17563517/9753)https://i89.servimg.com/u/f89/17/56/35/17/a211.png[/img][/url[/iurl]] LE TTGO est alimenté par un TP4054 qui permet de charger la batterie à 0.4A

https://datasheetspdf.com/pdf/1090540/NanJingTopPower/TP4054/1 Le régulateur de tension entre la tension Vin et la tension 3.3V AP2112. il peut supporter un courant de 0.6A et peut fonctionner pour une tension de 5V à 3V pour alimenter l’ESP32 https://www.mouser.fr/datasheet/2/115/AP2112-271550.pdf Le TTGO avec l’OLED demande un courant d’environ 0.06A sur la tension d’entrée Vin Le schématique du TTGO peut être téléchargé sur ce lien https://github.com/Xinyuan-LilyGO/TTGO-T-Display/blob/master/schematic/ESP32-TFT(6-26).pdf Voici le schéma électrique de notre TTGO ou le transistor mos est command able en 3.3V |500x305 Voici le PCB avec le logiciel ARES Proteus électronique pour commander l’éclairage

|500x318 Voici juste le programme qui permet d’écrire sur le OLED

#include 
#include 
#include     //https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/adc.html

#include "BluetoothSerial.h"
BluetoothSerial SerialBT;

TFT_eSPI tft = TFT_eSPI();  //library   1,4" color 135, 240
#define TFT_GREY 0x5AEB // New colour

String lire;
String myChar;
int a;

const int ledPin32 = 32;       //
const int ledChannel = 2;
float tension;



void espDelay(int ms)
{
    esp_sleep_enable_timer_wakeup(ms * 1000);
    esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
    esp_light_sleep_start();
}

void setup() {
  pinMode(33, OUTPUT);
  pinMode(2, INPUT);   

 Serial.begin(9600);

 SerialBT.begin("ESP32test"); //Bluetooth device name

    
 tft.init();
  tft.setRotation(0); //format portrait a l'endroit
    tft.fillScreen(TFT_BLACK);     
   

   tft.setCursor(0, 0, 2);// (x,y,taille)

  tft.setTextColor(TFT_WHITE,TFT_BLACK);  
  tft.setTextSize(1); //(taille)
  
  tft.println("IUT GEII Soissons");

  tft.setCursor(0, 16, 4);  //taille paire
  tft.setTextColor(TFT_RED,TFT_RED); //(couleur police,background police)
  tft.setTextSize(1);
  
  tft.println("Light Rear");
  tft.setTextColor(TFT_WHITE,TFT_BLACK);  
  tft.setTextSize(1); //(taille)

ledcSetup(ledChannel, 78000, 10);     //PWM 78kHz  10bits
ledcAttachPin(ledPin32, ledChannel);  //broche 32 et 22 Ok  36,37 ne fonctionne pas


adc1_config_width(ADC_WIDTH_BIT_12);
//adc1_config_channel_atten(ADC1_CHANNEL_0,ADC_ATTEN_DB_2_5);   // input voltage of ADC will be attenuated, extending the range of measurement to up to approx. 1100 mV????  5V
    
}

void loop() {
  if ( digitalRead(33)== 1 ) {digitalWrite(33,0);}  else {digitalWrite(33,1);}   //time loop 1ms
//digitalWrite(33,1);
ledcWrite(ledChannel, 512);         //ledcWrite(Channel, dutyCycle);   PWM=1 1024


tension=analogRead(2);          //https://randomnerdtutorials.com/esp32-adc-analog-read-arduino-ide/
tension=(tension*5)/4096;      //12bits     analogSetSamples (8)    https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/adc.html
tft.setCursor(0, 40, 2);// (x,y,taille)
tft.print(tension,2);

tft.setCursor(0, 60, 2);// (x,y,taille)  
a++;
tft.println(a);
//SerialBT.print(a); 
//Serial.print(a);

//digitalWrite(33,0);

/*
  while (SerialBT.available()) {       //lit une chaine
  lire=(SerialBT.readString());        //reception en char avec string oled pour affichage correcte mais un seul
  myChar=lire+1;                       //accusé de receptionen rajoutant 1
  SerialBT.print(myChar);      //ecrit au terminal bluetooth 
  } 
*/  
  
 // espDelay(10000);
}//fin loop

|500x292 Le oled peut permettre de dire le temps de fonctionnement restant en fonction de la mesure de la batterie, peut communiquer en Bluetooth sans utiliser de HC 06. Un des boutons peut permettre de gérer la consigne et la mise en veuille de l’éclairage.

Le codage doit aussi gérer la batterie lithium et ce mettre en veuille profonde si la tension batterie est inférieur à 3.2V pour ne pas décharger trop la batterie

Mais quelle est la consommation du TTGO pour connaitre l’autonomie de l’eclairage ? Sachant que les consommation theoriques sont sur ce lien

[Tuto] : Les sleep modes de l’ESP32 (letmeknow.fr)

2 Likes

[u]Comment choisir une led chez un distributeur(Farnell, radiospare…)?[/u] [u]Quelles sont les caractéristique entre une led rouge dite de puissance et de faible puissance ?[/u]

Les leds de faible puissance sont inférieures à 75mA chez les fournisseurs. Il y a des mots clefs (fabricant,couleur,intensité lumineuse (candela/lumen),CMS ou a trou, diamètre de la led, courant nominal, tension de seuil, angle de vision) Voici une recherche de led faible puissance. |500x208 Pour réaliser un éclairage arrière de vélo pour être vue de près sur les cotés un led de diamètre de 5mm suffit. Avec un angle de 8° Voici la led qui a le plus d’intensité lumineuse(65 candela) qui demande un courant de 50mA. |500x285 ces fournisseurs nous donne toujours les datasheets voici son liens : [u]https://4donline.ihs.com/images/VipMasterIC/IC/VISH/VISHS87555/VISHS87555-1.pdf?hkey=6D3A4C79FDBF58556ACFDE234799DDF0[/u] La conversion candela lumens est donné par l’équation suivante : Lumens = candela*2π(1-cos(Angle(π/180)) Lumens = 65*2π(1-cos(8(π/180)) Lumens = 130π(1-cos(8(π/180)) Lumens = 4 lumens Donc les lumens par Watt sont de 4/(2.2*0.05)= 36 lumens/W Ce qui est honorable sachant que a ce jour il n’est pas possible de dépasser les 50 lumens/W

Exemple les lux à 1m sera déterminer par l’équation suivante : Lux= (lumen*2)/(π(distance*tan(Angleπ/180))² = 128 Lux La température de jonction Tj= Temp ambiant+ Rthja*Puissance = 20+300*(2.2*0.05) = 53°C Est-ce qu’il est possible que cette led puisse fournir plus d’intensité lumineuse ? Voici la courbe des candela relative en fonction du courant sachant que pour 50mA on a 65 candela.

|474x269

Le point rouge ici présent représente les 100% de la led, mais on peut voir qu’on peut augmenter au-dessus de 100% comme ici avec le point voir qui a doublé donc on passe de 65 lumens à 130 lumens.

Sur la courbe données par le constructeur, il est possible d’alimenter la led en 100mA pour 120 candela (point vert). Mais sa durée de vie sera plus courte car la température de jonction sera plus importante : Tj= Temp ambiant+ Rthja*Puissance = 20°C+300*(2.4V*0.1A) = 92°C

Mais on a pas le MTBF en fonction de la température. Pour être vue à plus de 150m de jour, une led de 3W suffit. Mais ces leds ont un angle de 120° comme on peut l’observer sur les caractéristique du fournisseurs : |500x160 Voici le lien de la datasheet de la led cree qui fait 39 pages. Mais avec toutes les couleurs possibles. [u]http://www.farnell.com/datasheets/2574140.pdf[/u] |500x225 Le courant nominal est de 350mA |500x220 Nous avons déjà les lumens grâce au donnée constructeur qui est de 80.6 lumens.

Donc avec un exemple de lux à 10m on a: Lux= (lumen*2)/(π(distance*tan(Angleπ/180))² =0.36 Lux Par conséquent, il faut une optique qui concentre l’éclairage sur 4 ou 5°. La température de jonction Tj= Temp ambiant+ Rthja*Puissance. Tj=25+5°C/W*3W=40°C On peut faire une comparaison de la puissance en fonction du prix et une autre des lumens en fonction du prix. (Courbe faites en fonction de la led de puissance) Donc on a fait les 2 courbes ci-dessous :

|500x304

Figure 1: Courbe du Prix en fonction de la Puissance |500x302

Figure 2 : Courbe du Prix en fonction des Lumens

[u]Conclusion :[/u] Ce n’est pas si facile de trouver une led et cela prend beaucoup de temps à chercher chez les constructeurs. Avec les courbes (figure 1 et 2), on peut remarquer que le prix est en fonction du nombre de vente et non en fonction de l’efficacité de la led. Il y a une obsolescence rapide et une indisponibilité rapide des leds.

Évidemment sur aliexpress les caractéristique sont faibles et pas fiables. Par conséquent, il faut acheter quelqu’une et faire des mesures pour vérifier leurs données.

3 Likes

L'utilisation de la veille est fortement recommandée pour pouvoir garder de l'energie plus longtemps dans une batterie.

En mode deep_sleep le TTGO consommera 5mA alors qu'en fonctionnement il consomme en moyen 20mA avec le programme ci dessous sachant qu'il y a un delay de 500 ms qui tourne en boucle pour eviter que l'OLED se rafraichisse tout le temps au niveau du code. Sans le delay, la consommation passe à 120mA sans utiliser le OLED et 150mA avec le OLED et peut importe la couleur de fond

aavec le code suivant, pour mettre en veuille, il suffit d'appuyer sur le bouton 1 du TTGO

  #include 
#include 

TFT_eSPI tft = TFT_eSPI();  // Invoke library

   #define BUTTON_1            0    //fonctionne à 0L
   #define BUTTON_2            35// fonctionne à 0L et définir le BP en entrée au préalable en input
   int count=0;

   void espDelay(int ms)
{
    esp_sleep_enable_timer_wakeup(ms * 1000);
    esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
    esp_light_sleep_start();
}

void setup() {
    tft.init();
    tft.setRotation(0); //format portrait a l'endroit
    Serial.begin(115200);
    //Serial.println("setup");
    pinMode(BUTTON_2, INPUT_PULLUP);
    esp_sleep_enable_ext0_wakeup(GPIO_NUM_35,LOW);    //gpio_num: Numéro GPIO utilisé comme source de réveil. Seuls les GPIO dotés de la fonctionnalité RTC peuvent être utilisés: 0,2,4,12-15,25-27,32-39.
    tft.fillScreen(TFT_BLACK);
}

void loop() {
  if (!(digitalRead(BUTTON_1))){    //bouton1 actif à 0L
      esp_sleep_enable_timer_wakeup(120000000); //120 seconds
      /*int ret = esp_light_sleep_start();
      Serial.print("light_sleep:");
      Serial.println(ret);*/
      
      esp_deep_sleep_start();
      //esp_light_sleep_start();
      }
      count++;
   
   tft.setCursor(0, 0, 2);// (x,y,taille)
  // put your main code here, to run repeatedly:
  tft.setTextColor(TFT_WHITE,TFT_BLACK);  
  tft.setTextSize(1); //(taille)
  
  tft.println(count);

  espDelay(500);
  
    
}

5mA en deep sleep sur l'entree d'alimentation 5V, on est loin des 10micro ampere annoncé ????? comment mesurer la tension de la batterie et déterminer le temps restant de fonctionnement ?

3 Likes

Bat ADC input ADC34 part l’intermédiaire avec pont diviseur 100Kohm Voir le schématique du TTGO peut être téléchargé sur ce lien https://github.com/Xinyuan-LilyGO/TTGO-T-Display/blob/master/schematic/ESP32-TFT(6-26).pdf

Il y a 1 transistor (chanel P) Q4 qui permet à la batterie d’alimenter ESP32 via le transistor bipolaire Q3 commandé par la sortie PWR EN (IO14) ou par la tension Vde USB via un ou logique par 2 Diodes D1 et D6 S’il y a la tension VUSB alors Q3 est saturé, ainsi que Q4, donc la tension USB sera affichée et il est possible de verifier que la batterie se charge. Sachant qu’il y a une led qui s’allume tant que le courant batterie n’a pas nulle pour sa tension de seuil de 4.2V. Pour lire la tension en BAT_ADC, il faut mettre PWR_EN à « 1 ». mais il y a un peu pres 0.2V par defaut d'ecart entre la tension de la batterie et la valeur mesurée. Pour économiser la batterie, vous pouvez régler PWR_EN à « 0 » qui se décharge dans le pont diviseur de 200KΩ Quelque soit la tension Vin, c’est la tension Vbatt qui sera lu à cause du transistor Q5 Si Vin>Vbatt , la batterie. Si Vin|500x254 Voici le code qui donne la tension de la batterie en power Enable=1 en appuyant sur le bouton S1 pendant plus de 1 seconde

#include 
#include 
//#include     //https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/adc.html

#include "BluetoothSerial.h"
BluetoothSerial SerialBT;

TFT_eSPI tft = TFT_eSPI();  //library   1,4" color 135, 240
#define TFT_GREY 0x5AEB // New colour

String lire;
String myChar;
int a;

const int ledPin32 = 32;       //
const int ledChannel = 2;
const float vref=1100; 
float tension;
float tensionbatt;

#define ADC_PIN 34
   #define S1            0    //fonctionne à 0L, switch
   #define S2            35   //key



void setup() {
  pinMode(33, OUTPUT);
  pinMode(14, OUTPUT);   //power EN    
  pinMode(33, OUTPUT);
  pinMode(2, INPUT); 
  pinMode(34, INPUT);   //batterie 
  pinMode(35, INPUT);   //S2
  
   

 Serial.begin(9600);

 SerialBT.begin("ESP32test"); //Bluetooth device name

    
 tft.init();
  tft.setRotation(0); //format portrait a l'endroit

  tft.fillScreen(TFT_BLACK);     
   
   tft.setTextColor(TFT_BLUE,TFT_BLUE);
   tft.setCursor(0, 0, 2);// (x,y,taille)
   tft.println("IUT GEII Soissons");

  tft.setCursor(0, 16, 4);  //taille paire
  tft.setTextColor(TFT_RED,TFT_RED); //(couleur police,background police)
  tft.println("Light Rear");
  
  tft.setTextColor(TFT_WHITE,TFT_BLACK);  //raffraichi l'ecriture avec fond noir

ledcSetup(ledChannel, 78000, 10);     //PWM 78kHz  10bits
ledcAttachPin(ledPin32, ledChannel);  //broche 32 et 22 Ok  36,37 ne fonctionne pas

analogReadResolution(12);   //12 bits 
//analogSetAttenuation(ADC_2_5db);          // ADC_0db vref=5V ???    ADC_2_5db=1.4V
//analogSetPinAttenuation(2,ADC_2_5db );   //ne fonctionne pas ???
}




void loop() {

 // if ( digitalRead(33)==1 ) {digitalWrite(33,0);}  else {digitalWrite(33,1);}   //time loop 4ms
 digitalWrite(33,1);
  if (!(digitalRead(S1))){    //bouton1 actif à 0L
        tft.setCursor(0, 100, 2);// (x,y,taille)
        if ( digitalRead(14)==1 ) {digitalWrite(14,0);tft.print("PEN=0"); }  else {digitalWrite(14,1);tft.print("PEN=1");}   //active ou desactive la mesure de vbatt 
      }   
    if (!(digitalRead(S2))){esp_deep_sleep_start();   }  //consommation 5mA
      

ledcWrite(ledChannel, 512);         //ledcWrite(Channel, dutyCycle);   PWM=1 1024


tension=analogRead(2);           //https://randomnerdtutorials.com/esp32-adc-analog-read-arduino-ide/
tension=(tension*3.65)/4096;    //12bits     analogSetSamples (8)    https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/adc.html
tft.setCursor(0, 40, 4);         // (x,y,taille)
tft.print("in2=");tft.print(tension,4);

tensionbatt=analogRead(ADC_PIN);                      //34 interne, pont diviseur par 2 (100Kohm)
tensionbatt=(tensionbatt*2*3.3*vref)/(4095*1000);     //Vref=1.1V   sans batterie ce seria la tension Vbus

tft.setCursor(0, 70, 4);// (x,y,taille)
tft.print("Vbat=");tft.print(tensionbatt,3);

//if (tensionbatt<3.1) {esp_deep_sleep_start(); }


digitalWrite(33,0);
delay(1000);

}//fin loop

attention : ** **ne pas mettre Vin=5V avec un batterie lithium vous depasserez sa tension de seuil et la détruirait . il n'y pas de regulateur en Vin et la batterie

|500x243

pour connaitre l'autonomie , il faudrait mesurer le courant sortant de la batterie......

3 Likes

Donc, L’ESP32 consomme 2 fois plus que le pro mini 60mA….. Mais, la led de l’éclairage arrière est activé pendant à 50ms sur 1 seconde, il est possible de le mettre en dép. sleep pendant 950ms. Donc, la periode d’echantillonnage va passer à 1s Donc sa consommation moyenne passerait de (5mA*0.95s+120mA*0.05s)=10mA Par conséquent, à la place d’utiliser une routine d’interruption un delaysleep pourrait etre utiliser mais aussi pour l’Arduino nano Arduino, Zigbee and Embedded Development: Sleeping Arduino - Part 4 Wake Up Via Internal Timer (donalmorrissey.blogspot.com)

Pour le TTGO le bouton S1 permettrait d’augmenter la consigne de courant et le bouton S2 de diminuer la consigne. Le OLED permettrait d’afficher la consigne, la PWM, la tension batterie, Son connecteur USB permettait de gere la charger de la batterie lithium de 1.2A.h (25mm*40mm*5mm) pour gagner de la place. Dans le codage, un flag mettra l’allumage de la led pendant 5 seconde. Un interrupteur sera utilisé pour que la batterie ne se decharge pas meme si la tension de la batterie est diminuée

Voici le code de l’eclairage pour canal N et regulation de courant

#include 
#include 

#include "BluetoothSerial.h"
BluetoothSerial SerialBT;

TFT_eSPI tft = TFT_eSPI();  //library   1,4" color 135, 240

String lire;
String myChar;
int a;

const int ledPin32 = 32;       //
const int ledChannel = 2;
const float vref=1100; 

float consigne=0.2;
float courant;
float tensionbatt;
float erreur;
float Integral=512; //initialisation
const float ki =1;
int PWM;

byte flag=10;



#define ADC_PIN 34
   #define S1            0    //fonctionne à 0L, switch
   #define S2            35   //key



//********************************
void espDelay(int ms)
{   esp_sleep_enable_timer_wakeup(ms * 1000);
    esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
    esp_light_sleep_start(); }

void setup() {
  pinMode(33, OUTPUT);
  pinMode(14, OUTPUT);   //power EN    
  pinMode(33, OUTPUT);
  pinMode(2, INPUT); 
  pinMode(34, INPUT);   //batterie 
  pinMode(35, INPUT);   //S2 

 Serial.begin(9600);

 SerialBT.begin("ESP32test"); //Bluetooth device name

    
  tft.init();
  tft.setRotation(0); //format portrait a l'endroit

  tft.fillScreen(TFT_BLACK);     
   
  tft.setTextColor(TFT_WHITE,TFT_BLACK);  //raffraichi l'ecriture avec fond noir


ledcSetup(ledChannel, 78000, 10);     //PWM 78kHz  10bits
ledcAttachPin(ledPin32, ledChannel);  //broche 32 et 22 Ok  36,37 ne fonctionne pas

analogReadResolution(12);   //12 bits 
}




void loop() {

    if (!(digitalRead(S1)))    {consigne=consigne+0.1;flag=6;  tft.fillScreen(TFT_BLACK);   }   
    if (!(digitalRead(S2)))    {consigne=consigne-0.1;flag=6;  tft.fillScreen(TFT_BLACK);   }   
if (consigne>=1) {consigne=1;} 
if (consigne<=0.1)  {consigne=0.1;}

if (flag==0) {  
tft.fillScreen(TFT_RED);    
ledcWrite(ledChannel, PWM);
digitalWrite(14,0);
courant=analogRead(2);
courant=(courant*3.65)/(4096*0.5); 
erreur=consigne-courant;
Integral= Integral+erreur*ki;
      if (Integral>=1023) Integral=1023;
      if (Integral<=0) {Integral=0;}
      PWM=Integral;

espDelay(48);    //reste le temps allumé la led avec le programme precedent
ledcWrite(ledChannel, 0);   //extinction de la led pendant 950ms
espDelay(950); }



if (flag>0) {        //
digitalWrite(33,1);
PWM=512;
ledcWrite(ledChannel,PWM);     //ledcWrite(Channel, dutyCycle);   PWM=1 1024 10 bits 78kHz 
digitalWrite(14,1);  //lecture battery
flag--;   
   tft.setTextColor(TFT_BLUE,TFT_BLACK);
   tft.setCursor(0, 0, 2);// (x,y,taille)
   tft.println("IUT GEII Soissons");
    tft.setCursor(0, 16, 4);  //taille paire
    tft.setTextColor(TFT_RED,TFT_BLACK); //(couleur police,background police)
    tft.print("IC=");tft.print(consigne,2);

tft.setTextColor(TFT_WHITE,TFT_BLACK);                         
courant=analogRead(2);                //https://randomnerdtutorials.com/esp32-adc-analog-read-arduino-ide/
courant=(courant*3.65)/(4096*0.5);    //12bits     analogSetSamples (8)   0.5ohms
tft.setCursor(0, 40, 4);                        // (x,y,taille)  duree 2ms
tft.print("I=");tft.print(courant,2);   //4 cararcters 1ms

erreur=consigne-courant;
Integral= Integral+erreur*ki;
      if (Integral>=1023) Integral=1023;
      if (Integral<=0) {Integral=0;}
      PWM=Integral;

tft.setCursor(0, 40, 4);                       
tft.print("PWM=");tft.print(PWM);   

tensionbatt=analogRead(ADC_PIN);                      //34 interne, pont diviseur par 2 (100Kohm)
tensionbatt=(tensionbatt*2*3.3*vref)/(4095*1000);     //Vref=1.1V   sans batterie ce seria la tension Vbus

tft.setCursor(0, 70, 4);// (x,y,taille)
tft.print("Vbat=");tft.print(tensionbatt,3); 
digitalWrite(33,0);
delay(40);    //reste le temps allumé la led avec le programme precedent
ledcWrite(ledChannel, 0);   //extinction de la led pendant 950ms
delay(950); }
           

}//fin loop

|375x500 le courant moyen de decharge correspondra à l'equation suivante exemple pour une consigne de 0.5A (5mA*0.95s+(120mA+consigneLEDcourant)*0.05s)=0.035A

donc le temps de decharge pour une batterie de 1.2A.H sera de 33heures ce qui est tres honorable.

pourrait on utiliser le OLED comme eclairage arriere ? à 10cm, l'eclairage OLED allumé rouge fournit 6 lux. avec le back led , l'eclairage est de 7.5lux à 10cm ce qui est négligeable.

Il y a plusieurs façons de connaitre le temps restant de fonctionnement. Mais en voici 1 : En utilisant la capacité énergétique et divisé par le courant moyen estimé La capacité énergétique peut être déduit de la tension de la batterie qui est à 100% pour 4.2V et 0% à 3V

2 Likes

Voici le code qui donne l’estimation du temps restant de l’éclairage en fonction de la consigne

#include <TFT_eSPI.h>
#include <SPI.h>
#include <Wire.h>   

#include "BluetoothSerial.h"
BluetoothSerial SerialBT;

TFT_eSPI tft = TFT_eSPI();  //library   1,4" color 135, 240

String lire;
String myChar;
int a;

const int ledPin32 = 32;       //
const int ledChannel = 2;
const float vref=1100; 
const byte timescreen=20;   //temps d'affichage

float consigne=0.2;
float courant;
float tensionbatt;
float erreur;
float Integral=512; //initialisation
float pourcentage;
float timeduration;
const float ki =1;
int PWM;

byte flag=10;



#define ADC_PIN 34
   #define S1            0    //fonctionne à 0L, switch
   #define S2            35   //key



//********************************
void espDelay(int ms)
{   esp_sleep_enable_timer_wakeup(ms * 1000);
    esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
    esp_light_sleep_start(); }

void setup() {
  pinMode(33, OUTPUT);
  pinMode(14, OUTPUT);   //power EN    
  pinMode(33, OUTPUT);
  pinMode(2, INPUT); 
  pinMode(34, INPUT);   //batterie 
  pinMode(35, INPUT);   //S2 
//  pinMode(23, OUTPUT);   //reset oled 
   pinMode(4, OUTPUT);   //back led acit "1"
 
 Serial.begin(9600);
 Serial2.begin(9600, SERIAL_8N1, 25, 26);   //GPS tracker  Serial2 port  pins 25 (Rx) and 26 (Tx)
 SerialBT.begin("ESP32test"); //Bluetooth device name

    
  tft.init();
  tft.setRotation(0); //format portrait a l'endroit
  tft.fillScreen(TFT_BLACK);     
  tft.setTextColor(TFT_WHITE,TFT_BLACK);  //raffraichi l'ecriture avec fond noir


ledcSetup(ledChannel, 78000, 10);     //PWM 78kHz  10bits
ledcAttachPin(ledPin32, ledChannel);  //broche 32 et 22 Ok  36,37 ne fonctionne pas

analogReadResolution(12);   //12 bits 
}


void loop() {

    if (!(digitalRead(S1)))    {consigne=consigne+0.1;flag=timescreen; tft.fillScreen(TFT_BLACK);   }     //rafraichi tout l'ecran   
    if (!(digitalRead(S2)))    {consigne=consigne-0.1;flag=timescreen; tft.fillScreen(TFT_BLACK);   }   
if (consigne>=1) {consigne=1;} 
if (consigne<=0.1)  {consigne=0.1;}

courant=analogRead(2);
courant=(courant*3.65)/(4096*0.5); 
erreur=consigne-courant;
Integral= Integral+erreur*ki;
      if (Integral>=1023) Integral=1023;
      if (Integral<=0) {Integral=0;}
      PWM=Integral;
      //PWM=512;
ledcWrite(ledChannel,PWM);     //ledcWrite(Channel, dutyCycle);   PWM=1 1024 10 bits 78kHz 

//****** reste le temps allumé la led avec le programme precedent
espDelay(48);   

//**********  ecran rouge car consomme toujours meme en faisant un reset
if (flag==0) {   
 
//tft.fillScreen(TFT_RED); 
digitalWrite(14,0);     //plus de lecture battery
}

//***************
if (flag>0) {        //affichage des données
digitalWrite(33,1);
digitalWrite(4,1);    //avec back led et oled     consommation carte 25mA   
digitalWrite(14,1);  //lecture battery
flag--;   
   tft.setTextColor(TFT_BLUE,TFT_BLACK);
   tft.setCursor(0, 0, 2);// (x,y,taille)
   tft.println("IUT GEII Soissons");
   tft.setCursor(0, 16, 4);  //taille paire
   tft.setTextColor(TFT_RED,TFT_BLACK); //(couleur police,background police)
   tft.print("IC=");tft.print(consigne,2);

tft.setTextColor(TFT_WHITE,TFT_BLACK);                         
courant=analogRead(2);                //https://randomnerdtutorials.com/esp32-adc-analog-read-arduino-ide/
courant=(courant*3.65)/(4096*0.5);    //12bits     analogSetSamples (8)   0.5ohms
tft.setCursor(0, 40, 4);                        // (x,y,taille)  duree 2ms
tft.print("I=");tft.print(courant,2);   //4 cararcters 1ms

tft.setCursor(0, 40, 4);                       
tft.print("PWM=");tft.print(PWM);   

tensionbatt=analogRead(ADC_PIN);                      //34 interne, pont diviseur par 2 (100Kohm)
tensionbatt=(tensionbatt*2*3.3*vref)/(4095*1000);     //Vref=1.1V   sans batterie ce seria la tension Vbus

tft.setCursor(0, 70, 4);// (x,y,taille)
tft.print("Vbat=");tft.print(tensionbatt,3); 
digitalWrite(33,0);

pourcentage= map(tensionbatt*10, 30, 42, 0, 100);
tft.setCursor(0, 100, 4);// (x,y,taille)
tft.print("%=");tft.print(pourcentage,3); 
digitalWrite(33,0);

timeduration=(pourcentage*1.2)/((0.005+consigne*0.05)*100);          //time=(1.2A.h*poucentage/100)/(consommation*0.95+(Ic
pourcentage = map(tensionbatt*10, 30, 42, 0, 100);
tft.setCursor(0, 130, 4);                      // (x,y,taille)
tft.print("hour ");tft.print(timeduration,1);
digitalWrite(33,0);
}


//extinction de la led pendant 950ms
ledcWrite(ledChannel, 0);  
espDelay(950); 

}//fin loop

On pourrait faire un tracker GPS de cet éclairage mais quelle est la consommation d’un gy-neo6mv2 ?
Celui-ci consomme 55mA.
Par conséquent, étant donné qu’une sortie de ESP32 ne peut fournir que 40m A, il faut mettre un transistor pour commander le GPS pour minimiser la consommation comme on peut l’observer sur le schéma électrique suivant

2 Likes

Suite à la publication de 15 Mars 2021, ou le courant filtré par le condensateur en pratique provoque une fluctuation de courant et on a pas trop la place de mettre un condensateur plus gros.

un filtre numérique passe bas du second ordre a été réalisé pour avoir une mesure de courant plus lisse, voici les résultats obtenus. ces filtres ont ete etudiés ici, il n'y a qu'a faire un copier coler et mettre la frequence d'echantillonage et la frequence de coupure puis les coefficients sont calculées et donner sur l'afficheur LCD https://forum.arduino.cc/index.php?topic=668939.0

Pour une fréquence de coupure de 1Hz et une frecence d'echantillonage de 1OO Hz, en pratique on peut observer une bonne attenutaion du courant mais provoque un retard de la commande PWM à cause de la regulation.

|500x300

Pour une fréquence de coupure de 10Hz, en pratique

Sur cette courbe, on peut remarquer que l'attenuation des oscillations est correcte et provoque moins de retard de la mesure du courant courbe bleu par rapport à la courbe de mesure orange

Voici le programme :

// include the library code:
#include 
#include      //https://www.arduino.cc/en/Reference/SoftwareSerialBegin
#include 
#include 
#include        //chien de garde
//#include    //mise en veille
//#include 
#include "LowPower.h"     //https://github.com/rocketscream/Low-Power




#define BP3        2       // 
#define battery    A0      //relay magnetron

#define LED13    13

LiquidCrystal lcd(9, 8, 4, 10, 11, 7);   // LiquidCrystal lcd(rs, en, d4, d10, d11, d7);
// Configuration des variables


unsigned int temps=0, PWM2;    //temps de la routine d'interruption
byte  temps1=0,mode=1,PWM=255,Integralbyte,I_conv;   
float I=0,erreur=0,kp=10,ki=10,Ic=1,Integral=150;
bool depart=false;

float  entree=0,entree1=0,entree2=0;        
float  sortie=0,sortie1=0,sortie2=0;            
float out=0;
const float b1 =2;
const float b2 =1;            
float a1=0,a2=0;
float denominateur=0,Gain=0;
float  fe=100,fc=10;  //frequence de coupure desiréé    
SoftwareSerial serial(0,1);




// the setup function runs once when you press reset or power the board
void setup() {
   pinMode(5, OUTPUT);      //PWM
   pinMode(6, OUTPUT);      //PWM
   pinMode(LED13, OUTPUT);
   serial.begin(115200);


   Timer1.initialize(10000);           // initialize timer1, and set a 0,1 second period =>  100 000  pour 0.01s  10 000
   Timer1.attachInterrupt(callback);   // attaches callback() as a timer overflow interrupt
   lcd.begin(20, 4);                   //modifier pour un afficheur 20x4


   TCCR0B = (TCCR0B & 0b11111000) | 0x01;         //pin 5  64khz    http://playground.arduino.cc/Main/TimerPWMCheatsheet
                                            
   pinMode(A5, OUTPUT);
   pinMode(2, INPUT);
   analogWrite(5,0);
   attachInterrupt(digitalPinToInterrupt(2), interBP, LOW);   //routine d'interruption exterieur broche 2
   
   analogReference(INTERNAL);

   denominateur=(fe*fe+fe*fc*PI*sqrt(2)+fc*fc*PI*PI);
   a1=(fc*fc*PI*PI-fe*fe)*2/denominateur;
   a2=(fe*fe*fe*fe+(fc*fc*fc*fc*PI*PI*PI*PI))/(denominateur*denominateur)         ;                             //pow(base, exponent)
   Gain=(1+2+1)/(1+a1+a2);  
}



// Interruptions  tous les 0.01s fait par le timer1***********************************
void callback()  {

      entree=analogRead(A1);
      entree=entree*0.00215;     //I*1.1/(1024*0.5ohms)               
      
      entree2=entree1;      //entree(n-2)
      entree1=entree;       //entree(n-1)

      sortie2=sortie1;      //sortie(n-2)
      sortie1=sortie;       //sortie(n-1)


//sortie=entree+entree1*b1+entree2*b2+entree3*b3-sortie1*a1-sortie2*a2-sortie3*a3 ;   //filtre passe pas recursif ordre 3
    sortie=(entree+entree1*b1+entree2*b2-sortie1*a1-sortie2*a2) ;                        //filtre passe pas recursif ordre 2
//sortie=(entree*0.19+sortie*0.81);                                 //filtre passe bas    a1=0.992 pour une constante de temps de 10ms  Te=1ms durre algo 150us                                                                                   //filtre passe pas recursif ordre 1
//sortie= entree  ;                                                                                     //gain unitaire
      out=(sortie/Gain);


      erreur=Ic-entree;

   
      //Correcteur PI; PWM=ki*Erreur/P********************************************************
      Integral= Integral+erreur*ki; 
      if (Integral>=255) Integral=255;
      if (Integral<=0) {Integral=0;}
      Integralbyte=Integral;
      
      PWM=Integralbyte;// Rapport cyclique inversé car le transistor est un Canal P
                        // Rapport cyclique entre 255(100%) et 0 (0%)
      //serial.print(I); serial.print(",");    //
     // serial.print(PWM2); serial.println(",");                 
      if(PWM>0)
      analogWrite(5,PWM);    //commande de la LED de puissance
      PWM2=(Integralbyte*100)/255;

      serial.print(out);serial.print(";");serial.print(entree);serial.println(";");



}


//interruption exterieur front descendant de la broche 2
void interBP() { 
//interrupts();
  mode++;                  //incrementation des modes 
  if (mode>3) mode=1; 

  switch (mode) {
  case 1:Ic=1;Integral=180;   break;   //donne un ordre de grandeur de la valeur de la PWM=255*(Rshunt*Ic-Useuil)/Ubattery
  case 2:Ic=0.75;Integral=240;   break;
  case 3:Ic=1.5;Integral=250;   break;
     }
   } 

   
void loop() {  

  lcd.setCursor(0,0);
  lcd.print("fe=");
  lcd.print(fe,0);
  lcd.print(" fc=");
  lcd.print(fc,0);
  lcd.setCursor(0,1);
  lcd.print("b0=1 b1=2 b2=1 a0=1");
  lcd.setCursor(0,2);    
  lcd.print("a1=");
  lcd.print(a1,3);
  lcd.print(" a2=");
  lcd.print(a2,3);
  lcd.setCursor(0,3);  
  lcd.print("Gain=1/");
  lcd.print(Gain,1);

} // fin loop

voici la capture d'ecran de la simulation qui donne les coefficients et verifie les bonnes valeurs

2 Likes

A la place d’utiliser une routine d’interruption sur l'arduino nano ou pro mini, pour faire clignoter et réguler le courant la led de puissance….avec un mode allumer pendant environ 50ms sur une période de 1s.

Avec l’Arduino pro ou nano, la library lowPower va être utilisé, https://www.electroniclinic.com/arduino-sleep-modes-automatic-and-manual-to-save-power-arduino-deep-sleep/ sur ce lien, les consommations sont indiquées http://riton-duino.blogspot.com/2018/02/arduino-pro-mini-basse-consommation.html https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf Voici tout bêtement le programme avec juste une sortie que l’on met à 1 pendant 60ms et à 0 pendant 1s.

Attention, ce programme n’est pas simulable dans ISIS, cela ne fonctionne pas. Avec la PWM à 64KHz utilisant le timer0, il ne faut mettre en veille ce timer, De meme, si l’on utilise le Timer2 pour la PWM à 32KHz, il ne faudra pas mettre ce timer en veille.

//#include 
#include 
#include      
//https://github.com/rocketscream/Low-Power/blob/master/Examples/powerDownWakePeriodic/powerDownWakePeriodic.ino
//https://github.com/rocketscream/Low-Power/blob/master/LowPower.cpp

#define led13     13       // 13


byte PWM=0;



void setup() {
//pinMode(led13, OUTPUT);   //
pinMode(10, OUTPUT);      //PWM
pinMode(11, OUTPUT); 
  Serial.begin(9600); 
  TCCR2B = (TCCR2B & 0b11111000) | 0x01;         //pin 3 et 11  32khz    http://playground.arduino.cc/Main/TimerPWMCheatsheet  
                                                 //timer1      32khz      9 et 10
//   TCCR0B = (TCCR0B & 0b11111000) | 0x01;      //pin 5  64khz    http://playground.arduino.cc/Main/TimerPWMCheatsheet                                       
}


void loop() {  
   
//digitalWrite(led13,1);     //allume la led pendant 60mseconde
digitalWrite(10,1);          //allume la led pendant 60milliseconde
PWM=127,
analogWrite(11,PWM);  
//faire la regulation de courant en fonction de la led de puissance avec un temps de fonctionnement de 60ms 
LowPower.idle(SLEEP_60MS, ADC_OFF, TIMER2_ON, TIMER1_OFF, TIMER0_OFF,SPI_OFF, USART0_OFF, TWI_OFF);  //il ne faut pas utiliser le timer0 sinon ne fonctionne pas
//LowPower.powerDown(SLEEP_60MS, ADC_OFF, BOD_OFF);       //timer en 2 veuille donc ne pas utiliser
digitalWrite(10,0);      //eteint la led pendant 1 seconde
analogWrite(11,0);       //PWM=0   pendant 1 seconde
//LowPower.powerDown(SLEEP_1S, ADC_OFF, BOD_OFF); 
LowPower.idle(SLEEP_1S, ADC_OFF, TIMER2_ON, TIMER1_OFF, TIMER0_OFF,SPI_OFF, USART0_OFF, TWI_OFF);

} // fin loop

la wake up se fait avec le timer0 donc on ne peut plus utilisé le timer0, on aurrait voulu garder le timer0 et faire le wake up avec le timer 1 ou 2

Si on alimente l’Arduino nano sur le Vin, celui-ci consomme moins que s’il était alimenté directement par +5V avec une différence d’environ 3mA. Par contre, le fonctionnement du régulateur a besoin d’une tension Vin de 3.5V pour fonctionner. Alors que sur l’entrée +5V, l’Atmega 328 peut fonctionner avec une tension 3.1V. |500x99 il n’y a pas ce problème pour l’Arduino pro mini car il n’y a pas de regulateur 5V. On peut observer la différence de consommation avec la pro mini et l’Arduino nano avec le tableau suivant dans les differents modes de veuilles.

|500x98 pour avoir le timer0 pour la PWM et le wake-up avec le timer 1 tous les 50ms, avec un fonctionnement pendant 50ms et un etat sleep de 950ms. voici le code utilisant, la librairie Avr/sleep.h,

#include 
//#include 
#include 
#include 
#include 
//http://donalmorrissey.blogspot.com/2011/11/sleeping-arduino-part-4-wake-up-via.html    

#define led13     13       // 13
byte PWM=0;
byte temps;

//
void callback()  {
digitalWrite(10,1);
temps++;

if (temps==1)    {
power_timer0_enable();
PWM=127;      //dure 50ms
  //faire la regulation
 analogWrite(5,PWM);     
 }

if (temps==2)    {analogWrite(5,0);   //met en arret apres 50ms
 //enterSleep();          //ne fonctionne pas dans la routine
}       
if (temps>=10)   {temps=0;
}        

digitalWrite(10,0);
}//fin callback


void enterSleep(void)
{
  set_sleep_mode(SLEEP_MODE_IDLE);
//set_sleep_mode(SLEEP_MODE_ADC);
//set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  power_adc_disable();
  power_spi_disable();
 // power_timer0_disable();
  power_timer2_disable();
  power_twi_disable();  

  sleep_mode();     /* Now enter sleep mode. */
  
  /* The program will continue from here after the timer timeout*/
  sleep_disable(); /* First thing to do is disable sleep. */
  power_all_enable();     // Re-enable the peripherals. 
}


void setup() {
//pinMode(led13, OUTPUT);   //
pinMode(5, OUTPUT);      //PWM
pinMode(10, OUTPUT); 
 Serial.begin(9600); 

 Timer1.initialize(50000);           // initialize timer1, and set a 0,1 second period =>  100 000  pour 0.01s  10 000
 Timer1.attachInterrupt(callback);   // attaches callback() as a timer overflow interrupt

  
//  TCCR2B = (TCCR2B & 0b11111000) | 0x01;         //pin 3 et 11  32khz    http://playground.arduino.cc/Main/TimerPWMCheatsheet                                               
    TCCR0B = (TCCR0B & 0b11111000) | 0x01;      //pin 5  64khz    http://playground.arduino.cc/Main/TimerPWMCheatsheet                                
}


void loop() {  
        
    enterSleep();
  
} // fin loop
1 Like

Tracker GPS en cas de vol du velo

Impossible de faire fonctionner le shields GPS NEO-6M avec le TTGO et la bibliothèque Tinygpsplus. Au prealable, un test la communication UART sur les broches 25 RX et 26 TX du TTC avec une communication bleutooth avait té realisé. Ce shields GPS ne veut pas s’appairer….au satellite, sa led ne s’allume pas ?????? est ce qu’il y a une initialisation ????? http://gilles.thebault.free.fr/spip.php?article50 http://arduiniana.org/libraries/tinygpsplus/ le lien de son datasheet https://www.u-blox.com/sites/default/files/products/documents/NEO-6_DataSheet_(GPS.G6-HW-09005).pdf

donc on s’est rabattue OE 506 pour vérifier que l’on recevait les données du GPS et que sur les broches 25 RX et 26 TX du TTGO était reelement ok. CE GPS est cher, mais il a un bonne sensibilité meme en interieur pres d'une fenetre. voici la doc pour connaitre la trame envoyer par ce GPS http://cdn.sparkfun.com/datasheets/GPS/EM506_um.pdf Le programme affiche les trames de ce GPS sur le moniteur serie comme on peut l’observer sur la figure suivante. La boucle du programme se fait tous les 200ms. |500x305 la Longitude et latitude de Soissons est (3.360417, 49.402803) $GPGGA donne bien la latitude en 3 position et la longitude en 5 position de la table $GPPRMC donne aussi la latitude en 3 position et la longitude en 5 position de la table

on peut observer que le GPS donne le caractere $ mais qu’il n’y a pas la trame de donnée.....

/************************************
  Le GPS EM506 met en  moyenne 15s à 25s pour trouver des satellite.
  sa led clignote quand il est appairer  mais il y a une sortie qui l'indique
  http://cdn.sparkfun.com/datasheets/GPS/EM506_um.pdf
  *******************************************/
#include 

int recu,i;
bool flag=0;
TFT_eSPI tft = TFT_eSPI();  //library   1,4" color 135, 240

double latitude,longitude;
char reception[82];
void setup()  {
  pinMode(13,OUTPUT);
  Serial.begin(9600);
    Serial2.begin(4800, SERIAL_8N1, 25, 26);   //GPS tracker  Serial2 port  pins 25 (Rx) and 26 (Tx)   serial:8 bit de données pas de parités un bit de stop 
    tft.init();
    tft.setRotation(0); //format portrait a l'endroit
    tft.fillScreen(TFT_BLACK);
    Serial.print("ok");  
}

void loop() {

  digitalWrite(13,1);
  recu=Serial2.read(); 

  if (recu='

Maintenant, il faut afficher latitude, longitude sur l’écran, il y a des exemples sur ce lien, https://www.lextronic.fr/lextronic_doc/Applications_B.pdf https://projets-ima.plil.fr/mediawiki/images/d/d2/Rapport_Projet_2013_V5.pdf

){i=0; flag=1;}   //attend la lecture $ pour lire la trame //  Serial.print("ok3");      if(flag){    while(recu!='*' && i<82){  //lecture de la trame      reception[i]=recu;      i++;      recu=Serial2.read();    }        flag=0;   //    //tft.setTextColor(TFT_WHITE,TFT_BLACK);    //tft.print(reception);    tft.setCursor(0, 40, 2);// (x,y,taille)    tft.print("info");    Serial.print(reception); //82 caract =102 ms  envoie la trame sur le moniteur serie    digitalWrite(13,0);  // Serial.println("ok4");   //dure 5ms    //delay(1000);  }   } ```

Maintenant, il faut afficher latitude, longitude sur l’écran, il y a des exemples sur ce lien, https://www.lextronic.fr/lextronic_doc/Applications_B.pdf https://projets-ima.plil.fr/mediawiki/images/d/d2/Rapport_Projet_2013_V5.pdf

pour les données mesure du GPS, il n’est pas necessaire d’utiliser de bibilioteque pourtant de nombreux lien utilise les biblio https://lastminuteengineers.com/neo6m-gps-arduino-tutorial/

http://gilles.thebault.free.fr/spip.php?article50

http://arduiniana.org/libraries/tinygpsplus/

https://github.com/mikalhart/TinyGPSPlus/blob/master/src/TinyGPS%2B%2B.h

pas la peine d’utiliser une libraie NMEA, meme si on passe de caratere en int https://github.com/stevemarple/MicroNMEA/blob/master/src/MicroNMEA.cpp https://bvdp.inetdoc.net/wiki/doku.php?id=tpethindus2

en effet, il faut savoir si le GPS est actif ou pas avec des données valides ou pas avant de les afficher |500x422 De plus, il faut vider l’UART pour avoir une trame complete, comme on peut l'observer sur la figure precedente

voici le code qui donne l'heure avec le décalage horaire voulue

/************************************
  Le GPS EM506 met en  moyenne 15s à 25s pour trouver des satellite.
  sa led clignote quand il est appairer  mais il y a une sortie qui l'indique
  http://cdn.sparkfun.com/datasheets/GPS/EM506_um.pdf
  *******************************************/
#include 

byte recu,i,x,fin;
bool flag=0;
int heure;


TFT_eSPI tft = TFT_eSPI();  //library   1,4" color 135, 240


char reception[82];

char data;

void setup()  {
  pinMode(13,OUTPUT);
  Serial.begin(9600);
    Serial2.begin(4800, SERIAL_8N1, 25, 26);   //GPS tracker  Serial2 port  pins 25 (Rx) and 26 (Tx)   serial:8 bit de données pas de parités un bit de stop 
    tft.init();
    tft.setRotation(0); //format portrait a l'endroit
    tft.fillScreen(TFT_BLACK);
}

void loop() {

  digitalWrite(13,1);

  while (Serial2.available()) {
    data = Serial2.read();
         if  (data=='

|500x375

maintenant, il faudrait d’envoyer les coordonnées par le wifi, ou par SMS via un GSM par une carte SIM 800

) {x=0;}         if  (x<82){x++; if (x>=82) {x=82;}                   reception[x]=data;         if  (data=='*'){fin=x;}                                              }    //Serial.print(data);                      }//fin while

    for (i=0; i

    tft.setCursor(0, 0, 2);     for (i=4; i<=6; i++) {tft.print(reception[i]);}     //type de reception RMC, GGA          if (reception[4]=='R' && reception[5]=='M' && reception[6]=='C')  {                                                    tft.setCursor(0, 30, 2);// (x,y,taille)        heure=((int(reception[8]-48))*10+2+(int(reception[9]-48)));    // 2 heures de decalage de l'heure    if (heure==24) {heure=0; }    if (heure==25) {heure=1; }    tft.print(heure);    tft.print("H");    tft.print(reception[10]);tft.print(reception[11]);    tft.print("m");    tft.print(reception[12]);tft.print(reception[13]);    tft.println("s");        if  (reception[19]=='A')  {                           //validation                                        for (i=21; i <= 29; i++) {tft.print(reception[i]);}   //latitude      tft.println("  la ");      for (i=33; i <= 42; i++) {tft.print(reception[i]);}      tft.println("  Lo");      for (i=46; i <= 49; i++)  {tft.print(reception[i]);}      tft.println(" Speed ");      }             }  //fin if $GPRMC                                                          

/*                                                      if (reception[3]=='G' && reception[4]=='G' && reception[5]=='A')  {                                                    tft.setCursor(0, 80, 2);// (x,y,taille)    for (i=52; i <= 55; i++) {tft.print(reception[i]);}   //altitude    tft.print(" Altitu");                       }  //fin if $GPGGA */  

                 

  digitalWrite(13,0); }  //fin loop ```

|500x375

maintenant, il faudrait d’envoyer les coordonnées par le wifi, ou par SMS via un GSM par une carte SIM 800