Vélo-scooter électrique

Il y à des signes de progression

if((millis() - valeurPrecedente2) > 60000){

Tu peux utiliser le même principe pour la vitesse

Tu utilise A0 pour le contrôle de la batterie mais aussi pour la vitesse.

display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(74, 2);
  display.print("km");

  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(52, 18);
  display.print("km/h");

T"es obligé de ré-écrire la même chose à chaque loop?

fdufnews t'a offert une solution très élégante pour la batterie. T'as préféré mon code (en réalité c'est le tien, juste amélioré) car (je pense) plus facile à comprendre. Essaye de le remplacer avec la solution de fdufnews.

En effet, je n’ai pas tout compris au code de fdufnews, surtout la deuxième courbe “charge” et le calcul qui la définie.

En fait, le but est si j’ai bien compris, est de calculer direct la variable restant grâce à l’info analogRead ???

En tout cas j’ai réalisé un code qui réactualise l’affichage de la vitesse et de la distance toute les secondes en utilisant le même principe que pour le pourcentage batterie.

#include <Adafruit_SSD1306.h>
#include <splash.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SPITFT.h>
#include <Adafruit_SPITFT_Macros.h>
#include <gfxfont.h>
#define OLED_RESET 4
Adafruit_SSD1306 display( OLED_RESET );


 
#define valMin 410                          // Définir ici les seuils min      2v
#define valMax 615                          // et max de l'analogRead.         3v
 
const int valMoy = (valMin + valMax) / 2;
const int seuil = (valMax - valMin) / 2;
const int perimetre = 2;                    //entrer le périmètre de la roue en m, le périmètre est égal à   pi*diamètre     ou      pi*2* rayon                       !!!!! EN METRE !!!!!
bool flagMesure = false;
unsigned long tempstrouve = 0;
unsigned long dernierPassage = 0;
long valeurPrecedente2 = -60000;        //on met - 6000 pour que les infos batteries apparaissent dés le début
long valeurPrecedente1 = -1000;         //délai de réactualisatioin de l'affichege v et d
float vitesse = 0;
float distance = 0;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void Compteur (float distance, float vitesse) {

 if((millis() - valeurPrecedente1) > 1000 ){
  display.setTextSize(1);
  display.setTextColor(WHITE, BLACK);
  display.setCursor(53, 2);
  display.print(distance, 1);

  display.setTextSize(4);
  display.setTextColor(WHITE, BLACK);
  display.setCursor(0, 2);
  display.print(vitesse, 0);
 
  display.display();
 }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void setup () {
  display.begin( SSD1306_SWITCHCAPVCC, 0x3C );
  display.clearDisplay();
  Compteur (distance, vitesse);
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void loop() {
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(74, 2);
  display.print("km");

  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(52, 18);
  display.print("km/h");
  
  int diff = abs(analogRead(A1) - valMoy);
  if (diff >= seuil) { //si un aimant pole nord ou un aimant pole sud passe devant le capteur
    if (flagMesure) {
      tempstrouve = millis() - dernierPassage;
      dernierPassage = millis();
      vitesse = (perimetre / (tempstrouve / 1000.0)) * 3.6; //donne la vitesse en km/h grace à v = d/t
      flagMesure = false;     // pour attente cycle suivant
      distance = distance + (perimetre / 1000.0);
      Compteur (distance, vitesse);
    }
  }
  else
  {
    flagMesure = true;  // prêt pour une nouvelle mesure
  } 


if((millis() - valeurPrecedente2) > 60000){                                                                                            //réactualisation donc calculs du pourcentage batterie toutes les min

    display.display();
    display.drawRect( 101,  0,  27,  11,  WHITE);  //changer les x et y ( la position)              ligne 1
    display.drawRect( 96,  3,  5,  5,  WHITE);  //si ligne 1 changé de position, faire 2 premieres valeurs -3 et les recopier
    display.display();
  
    
    int restant;
 
  if ( analogRead(A0)> 868) {
    restant = 100; }
  else if ( analogRead(A0)> 861 ) {
    restant = 90; }
  else if ( analogRead(A0)> 853 ) {
    restant = 80; }
  else if ( analogRead(A0)> 844 ) {
    restant = 70; }
  else if ( analogRead(A0)> 835 ) {
    restant = 60; }
  else if ( analogRead(A0)> 825 ) {
    restant = 50; }
  else if ( analogRead(A0)> 816 ) {
    restant = 40; }
  else if ( analogRead(A0)> 806 ) {
    restant = 30; }
  else if ( analogRead(A0)> 795 ) {
    restant = 20; }
  else if ( analogRead(A0)> 785 ) {
    restant = 10; }
  else if ( analogRead(A0)< 785 ) {
    restant = 0; }
  
    display.fillRect( 102,  1,  25,  9,  BLACK);
    display.setTextSize(1);
    display.setTextColor(WHITE);
    display.setCursor(103, 2);
    display.print(restant);
    display.print("%");
    display.display();
}
    
}

Ce code réactualise le pourcentage batterie toutes les minutes, réactualise la vitesse et la distance toutes les secondes.

En tout cas j'ai réalisé un code qui réactualise l'affichage de la vitesse et de la distance toute les secondes en utilisant le même principe que pour le pourcentage batterie.

Super.

En fait, le but est si j'ai bien compris, est de calculer direct la variable restant grâce à l'info analogRead ???

Exacte.

Fait attention à ça

Là tu es obligé de faire un calcul en flottant mais en contrepartie tu bénéficies d'un variation continue de l'état de ta batterie. il faut quand même prendre la précaution de forcer l'affichage à 100% si l'ADC retourne une valeur supérieure à 868.

Essaye de le faire. Je t'aiderai si t'as besoin.

T"es obligé de ré-écrire la même chose à chaque loop?

Tu ne m'a pas répondu. Je pense que

display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(74, 2);
  display.print("km");

  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(52, 18);
  display.print("km/h");

tu peut le mettre dans le "setup".

tu peux mettre dans le setup même le symbole "%" du pourcentage de la batterie. comme ça tu dois effacer un rectangle plus petit et pas besoin de le ré-écrire.

Tu n'ai pas obligé de écrire   display.setTextColor(WHITE); à chaque fois que tu écris quelque chose sur l’écran, sauf si tu veut changer de couleur.

Ce code est très contreproductif

  if ( analogRead(A0)> 868) {
    restant = 100;
  }

  else if ( analogRead(A0)> 861 ) {
    restant = 90;
  }

  else if ( analogRead(A0)> 853 ) {
    restant = 80;
  }

L'analogRead qui se répète à chaque test est très couteux en temps d'exécution. Il faut faire comme ça

unsigned int mesure=analogRead(A0);
  if ( mesure> 868) {
    restant = 100;
  }

  else if ( mesure> 861 ) {
    restant = 90;
  }

  else if ( mesure> 853 ) {
    restant = 80;
  }

Pour ma seconde proposition

 restant = 10 + (unsigned int) ((analogRead(A0)-785)*1,0843);

D’accord, j’ai fait ça.
J’ai mis tous les affichages “perpétuels” dans un void affiche qui se lançe à chaque début de loop mais qui vérifie à chaque fois si on a déjà affiché.
En gros ca met nbffois à 1 la premiere fois donc ca ne l’affiche plus jamais.

#include <Adafruit_SSD1306.h>
#include <splash.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SPITFT.h>
#include <Adafruit_SPITFT_Macros.h>
#include <gfxfont.h>
#define OLED_RESET 4
Adafruit_SSD1306 display( OLED_RESET );


 
#define valMin 410                          // Définir ici les seuils min      2v
#define valMax 615                          // et max de l'analogRead.         3v
 
const int valMoy = (valMin + valMax) / 2;
const int seuil = (valMax - valMin) / 2;
const int perimetre = 2;                    //entrer le périmètre de la roue en m, le périmètre est égal à   pi*diamètre     ou      pi*2* rayon                       !!!!! EN METRE !!!!!
bool flagMesure = false;
unsigned long tempstrouve = 0;
unsigned long dernierPassage = 0;
long valeurPrecedente2 = -60000;        //on met - 6000 pour que les infos batteries apparaissent dés le début
long valeurPrecedente1 = -1000;         //délai de réactualisatioin de l'affichege v et d
float vitesse = 0;
float distance = 0;
boolean nbrfois = 0;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void Compteur (float distance, float vitesse) {

 if((millis() - valeurPrecedente1) > 1000 ){
  display.setTextSize(1);
  display.setTextColor(WHITE, BLACK);
  display.setCursor(53, 2);
  display.print(distance, 1);

  display.setTextSize(4);
  display.setTextColor(WHITE, BLACK);
  display.setCursor(0, 2);
  display.print(vitesse, 0);
 
  display.display();
 }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void Affiche(){
  if( nbrfois == 0){
    nbrfois = 1;
    
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(74, 2);
  display.print("km");

  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(52, 18);
  display.print("km/h");

  display.display();
  display.drawRect( 101,  0,  27,  11,  WHITE);  //changer les x et y ( la position)              ligne 1
  display.drawRect( 96,  3,  5,  5,  WHITE);  //si ligne 1 changé de position, faire 2 premieres valeurs -3 et les recopier
  display.display();  
  }
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void setup () {
  display.begin( SSD1306_SWITCHCAPVCC, 0x3C );
  display.clearDisplay();
  Compteur (distance, vitesse);
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void loop() {
Affiche;
 
  int diff = abs(analogRead(A1) - valMoy);
  if (diff >= seuil) { //si un aimant pole nord ou un aimant pole sud passe devant le capteur
    if (flagMesure) {
      tempstrouve = millis() - dernierPassage;
      dernierPassage = millis();
      vitesse = (perimetre / (tempstrouve / 1000.0)) * 3.6; //donne la vitesse en km/h grace à v = d/t
      flagMesure = false;     // pour attente cycle suivant
      distance = distance + (perimetre / 1000.0);
      Compteur (distance, vitesse);
    }
  }
  else
  {
    flagMesure = true;  // prêt pour une nouvelle mesure
  } 


if((millis() - valeurPrecedente2) > 60000){                                                                               //réactualisation donc calculs du pourcentage batterie toutes les min
    
    unsigned int restant;

    restant = 10 +( unsigned int )((analogRead(A0)-785)*1.0843); 
  
    display.fillRect( 102,  1,  25,  9,  BLACK);
    display.setTextSize(1);
    display.setTextColor(WHITE);
    display.setCursor(103, 2);
    display.print(restant);
    display.print("%");
    display.display();
}
    
}

Il ne reste plus qu’a inclure ( et refaire ) le code clignotants et réaliser les tests.

Pour rappel, le code clignotants avait comme problème le “while” qui bloquait le code.

savoriano:

while(digitalRead(clignotantgauche) == 1)

While monopolise ton arduino pendant tout le temps du clicnotage.

Le code clignotants en ce moment

/*ce programme permet l'ajout de clignotants et warning sur un véhicule 
 * matériel: - 8 leds jaunes
 *           - 8 résistances 180 Ohms pour les leds
 *           - 1 interrupteur 3 positions ET UN AUTRE 2 POSITIONS
 *           - 1 arduino
 *           - des fils
 *           
 *bien cabler les leds dans l'ordre sinon ce ne sera plus un chenillard : schema clignotant visuel ci dessous
 *
 *  pin13  pin12  pin11  pin10                         pin6   pin7   pin8   pin9
 *  0      0      0      0                             0      0      0      0
 *  Led4G  Led3G  Led2G  Led1G                         Led1D  Led2D  Led3D  Led4D 
 *  
 *  pour plus de confort, rajout de leds entre sorties des interrupteurs pour faire leds temoins
 */


//définie les pins de déclenchement des clignotants et d'arrêt de ceux-ci
int clignotantgauche = 0;
int clignotantdroit = 1;
int warning = 2;

//définie toutes les pins pour clignotants
int Led1D = 6;   
int Led2D = 7;
int Led3D = 8;
int Led4D = 9;

int Led1G = 10;
int Led2G = 11;
int Led3G = 12;
int Led4G = 13;



void setup() {
  
   //définie les pins de déclenchement comme entrées = INPUT
   pinMode(clignotantgauche, INPUT_PULLUP);
   pinMode(clignotantdroit, INPUT_PULLUP);
   pinMode(warning, INPUT_PULLUP);

  
//Définie les pins clignotants comme sortie = OUTPUT
  pinMode(Led1D,OUTPUT);
  pinMode(Led2D,OUTPUT);
  pinMode(Led3D,OUTPUT);
  pinMode(Led4D,OUTPUT);

  pinMode(Led1G,OUTPUT);
  pinMode(Led2G,OUTPUT);
  pinMode(Led3G,OUTPUT);
  pinMode(Led4G,OUTPUT);  
}

void loop() {

unsigned long temps;
byte intervalle = 100;
byte nbr;
  
   while(digitalRead(clignotantgauche) == 1){   // si on active le clignotant gauche chenillard vers la gauche
    
    temps = millis();
    digitalWrite(Led1G, HIGH);  }
    nbr = 1;

    if((millis() - temps) > intervalle and nbr == 8){
      temps = millis();
      nbr = 1;
      digitalWrite(Led1G, HIGH);  }
    
    else if((millis() - temps)> intervalle and nbr == 1){
      temps = millis();
      nbr = 2;
      digitalWrite(Led2G, HIGH);  }
      
    else if((millis() - temps)> intervalle and nbr == 2){
      temps = millis();
      nbr = 3;
      digitalWrite(Led3G, HIGH);  }
      
    else if((millis() - temps)> intervalle and nbr == 3){
      temps = millis();
      nbr = 4;
      digitalWrite(Led4G, HIGH);  }
      
    else if((millis() - temps)> intervalle and nbr == 4){
      temps = millis();
      nbr = 5;
      digitalWrite(Led1G, LOW);  }
      
    else if((millis() - temps)> intervalle and nbr == 5){
      temps = millis();
      nbr = 6;
      digitalWrite(Led2G, LOW);  }
      
    else if((millis() - temps)> intervalle and nbr == 6){
      temps = millis();
      nbr = 7;
      digitalWrite(Led3G, LOW);  }
      
    else if((millis() - temps)> intervalle and nbr == 7){
      temps = millis();
      nbr = 8;
      digitalWrite(Led4G, LOW);  }
}

En gros, ce code dit si le delai et dépassé et que l’action d’avant est faite, …
La variable nbr permet de savoir si l’action précedente est réalisée, la variable temps permet de faire un délai non bloquant.

Je pense que comme ça, ça devrai aller, je veux un code totalement non bloquant et donc je pense avoir réussi pour celui-ci.

je veux un code totalement non bloquant

Ton code il n'est pas bloqué avec un delay mais il est toujours bloqué à l’intérieur du while. Il ne fait que s'occuper des clignotants jusqu'à que digitalRead(clignotantgauche) == 0.

while(digitalRead(clignotantgauche) == 1)

il faut virer while. T'as regardé le code que je t'avais proposé?

Si l’on remplace while par

if (digitalRead(clignotantgauche) == 1){...

Et qu’on met la suite du code

if(digitalRead(clignotantgauche) == 1){   // si on active le clignotant gauche, chenillard vers la gauche
    
    temps = millis();
    digitalWrite(Led1G, HIGH);
    nbr = 1;

    if((millis() - temps) > intervalle and nbr == 8){
      temps = millis();
      nbr = 1;
      digitalWrite(Led1G, HIGH);  }
    
    else if((millis() - temps)> intervalle and nbr == 1){
      temps = millis();
      nbr = 2;
      digitalWrite(Led2G, HIGH);  }
      
    else if((millis() - temps)> intervalle and nbr == 2){
      temps = millis();
      nbr = 3;
      digitalWrite(Led3G, HIGH);  }
      
    else if((millis() - temps)> intervalle and nbr == 3){
      temps = millis();
      nbr = 4;
      digitalWrite(Led4G, HIGH);  }
      
    else if((millis() - temps)> intervalle and nbr == 4){
      temps = millis();
      nbr = 5;
      digitalWrite(Led1G, LOW);  }
      
    else if((millis() - temps)> intervalle and nbr == 5){
      temps = millis();
      nbr = 6;
      digitalWrite(Led2G, LOW);  }
      
    else if((millis() - temps)> intervalle and nbr == 6){
      temps = millis();
      nbr = 7;
      digitalWrite(Led3G, LOW);  }
      
    else if((millis() - temps)> intervalle and nbr == 7){
      temps = millis();
      nbr = 8;
      digitalWrite(Led4G, LOW);  }
}
}

Ca peut marcher ?
J’ai peur que dés que ça fini la boucle ça quitte le programme et moi je souhaite que ça quitte le programme uniquement si l’interrupteur clignotantgauche est LOW.

bonjour Belo. Ton code n'est pas bloquant. Par contre il ne fera pas ce que tu veut.

if((millis() - temps) > intervalle and nbr == 8)

le "and" ça s'écrit "&&" Moi je mets toujours des parenthèses , je ne sais plu si c'est un must ou si c'est un tic.

if(((millis() - temps) > intervalle) && (nbr == 8))
if(digitalRead(clignotantgauche) == 1){   // si on active le clignotant gauche, chenillard vers la gauche
   
    temps = millis();
    digitalWrite(Led1G, HIGH);
    nbr = 1;

à chaque loop et si clignotantgauche==1 temps sera toujours = millis() Led1G toujours = HIGH et nrb aussi toujours = 1

savoriano: à chaque loop et si clignotantgauche==1 temps sera toujours = millis() Led1G toujours = HIGH et nrb aussi toujours = 1

J'ai corrigé Led1G toujours HIGH, elle est comme les autres. J'ai corrigé nbr aussi toujours 1, il change de 1à 8.

Mais je n'ai pas corrigé temps = millis() car je ne sais pas comment faire. Je veux que quand je dise temps = millis(), ça mette la variable temps à la valeur actuelle de millis(), je ne veux pas que ça compte millis.

Maintenant que ton code n'est plus bloquant, il faut que ta variable temps soir une variable globale. Tu peux faire comme ça si tu veux garder ta philosophie:

unsigned long temps = 0;

void loop() {
if(digitalRead(clignotantgauche) == HIGH){   // si on active le clignotant gauche, chenillard vers la gauche
  
    if (temps == 0) temps = millis();
......
}

il faut penser de remettre temps = 0 quand ton clignotantgauche retournera à 0; Essaye et tu me dira si ça marche.

Ok, mais par contre comment remettre à 0 le temps quand clignotantgauche == 0 ?

Je pensais faire ça mais bon...

if(digitalRead(clignotantgauche) == LOW) {

temps = 0;
}

encore mieux

if(digitalRead(clignotantgauche) == HIGH){   // si on active le clignotant gauche, chenillard vers la gauche

    if (tempsGauche == 0) tempsGauche = millis();
......
} else tempsGauche = 0;

Donc tu dois avoir 2 variables temps (ex tempsGauche tempsDroite) ou

if((digitalRead(clignotantgauche) == LOW) && (digitalRead(clignotantdroite) == LOW)) {

temps = 0;
}

Merci, j'ai opté pour la solution 2

savoriano: ``` if((digitalRead(clignotantgauche) == LOW) && (digitalRead(clignotantdroite) == LOW)) {

temps = 0; }

Mieux encore:

if((temps != 0) && (digitalRead(clignotantgauche) == LOW) && (digitalRead(clignotantdroite) == LOW)) {

temps = 0;
}

ça évite de lire les portes la plus part du temps.

Bonjourà tous et excusez moi pour mon retard. :slightly_frowning_face:
Finalement j’ai opté pour une solution de clignotants simples comme les voitures. Ce n’est plus un chenillard mais un simple clignotant.
Voici le code:

/*ce programme permet l'ajout de clignotants et warning sur un véhicule 
 * matériel: - 8 leds jaunes
 *           - 8 résistances 180 Ohms pour les leds
 *           - 1 interrupteur 3 positions ET UN AUTRE 2 POSITIONS
 *           - 1 arduino
 *           - des fils
 *           
 *bien cabler les leds dans l'ordre
 *
 *  pin13  pin12  pin11  pin10                         pin6   pin7   pin8   pin9
 *  0      0      0      0                             0      0      0      0
 *  Led4G  Led3G  Led2G  Led1G                         Led1D  Led2D  Led3D  Led4D 
 *  
 *  pour plus de confort, rajout de leds entre sorties des interrupteurs pour faire leds temoins
 */


//définie les pins de déclenchement des clignotants et d'arrêt de ceux-ci
int clignotantgauche = 3;
int clignotantdroit = 2;
int warning = 4;

unsigned long temps = 0;
byte intervalle = 100;
bool moment = 0;

//définie toutes les pins pour clignotants
int Led1D = 6;   
int Led2D = 7;
int Led3D = 8;
int Led4D = 9;

int Led1G = 10;
int Led2G = 11;
int Led3G = 12;
int Led4G = 13;



void setup() {
  
   //définie les pins de déclenchement comme entrées = INPUT
   pinMode(clignotantgauche, INPUT_PULLUP);
   pinMode(clignotantdroit, INPUT_PULLUP);
   pinMode(warning, INPUT_PULLUP);

  
//Définie les pins clignotants comme sortie = OUTPUT
  pinMode(Led1D,OUTPUT);
  pinMode(Led2D,OUTPUT);
  pinMode(Led3D,OUTPUT);
  pinMode(Led4D,OUTPUT);

  pinMode(Led1G,OUTPUT);
  pinMode(Led2G,OUTPUT);
  pinMode(Led3G,OUTPUT);
  pinMode(Led4G,OUTPUT);  
}

void loop() {
  
   if(digitalRead(clignotantgauche) == HIGH){   // si on active le clignotant gauche, chenillard vers la gauche

    temps = millis();

if(millis() - temps > intervalle){
  moment = 1;
   digitalWrite(Led1G, HIGH);
   digitalWrite(Led1G, HIGH);
   digitalWrite(Led1G, HIGH);
   digitalWrite(Led1G, HIGH);
}
else if((millis - temps > intervalle) && (moment == 1)){
   digitalWrite(Led1G, LOW);
   digitalWrite(Led1G, LOW);
   digitalWrite(Led1G, LOW);
   digitalWrite(Led1G, LOW);
   moment = 0;
}
}
    
    
if((temps != 0) && (digitalRead(clignotantgauche) == LOW) && (digitalRead(clignotantdroit) == LOW)) {
  temps = 0;
}


}

Je ne suis pas sûr pour la variable moment mais je pense que ça peut marcher.

J’ai testé le code batterie et compteur mais

restant = 10 + (unsigned int) ((analogRead(A0)-785)*1,0843);

ne marchait pas. Je n’ai pas compris mais j’ai donc remplacé par le code d’avant; vu que ça ne réactualise que toutes les minutes ( je verrai si toutes les min ça convient, peut être faudrait-il toutes les 30s ou toutes les 5min !!!.. ), je laisse comme ça pour l’instant.

J’ai mis tous les affichages perpetuels dans une condition if qui ne s’execute qu’une seule fois, au début du programme. ( grâce à la variable nbrfois qu’on met à 1 quand c’est exécuté )
Voir partie AFFICHAGE PERPETUEL**

Le code complet du compteur et de la batterie. L’ayant testé sur breadboard, il marche mais il faudrait voir ça sur le vélo, en condition réelle. Mais bon, je n’ai pas encore tout construit : les boîtiers, la transmission du moteur …

#include <Adafruit_SSD1306.h>
#include <splash.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SPITFT.h>
#include <Adafruit_SPITFT_Macros.h>
#include <gfxfont.h>
#define OLED_RESET 4
Adafruit_SSD1306 display( OLED_RESET );
 
#define valMin 410                          // Définir ici les seuils min      2v
#define valMax 615                          // et max de l'analogRead.         3v
 
const int valMoy = (valMin + valMax) / 2;
const int seuil = (valMax - valMin) / 2;
const int perimetre = 2;                    //entrer le périmètre de la roue en m, le périmètre est égal à   pi*diamètre     ou      pi*2* rayon                       !!!!! EN METRE !!!!!
bool flagMesure = false;
unsigned long tempstrouve = 0;
unsigned long dernierPassage = 0;
long valeurPrecedente1 = -1000;
float vitesse;
float distance;
bool nbrfois = 0; 

byte restant = 0;
long valeurPrecedente2 = -60000;        //on met - 60000 pour que les infos batteries apparaissent dés le début
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////VOID COMPTEUR

void Compteur (float distance, float vitesse) {

  display.setTextSize(1);
  display.setTextColor(WHITE, BLACK);
  display.setCursor(53, 2);
  display.print(distance, 1);

  display.setTextSize(4);
  display.setTextColor(WHITE, BLACK);
  display.setCursor(0, 2);
  display.print(vitesse, 0);
 
  display.display();
 }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////VOID SETUP

void setup () {
  display.begin( SSD1306_SWITCHCAPVCC, 0x3C );
  display.clearDisplay();
  Compteur (distance, vitesse);
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////VOID LOOP

void loop() {
//***************************************************************AFFICHAGE PERPETUEL,NE S'EFFECTUE QU'UNE FOIS****************************************************************
 if(nbrfois == 0){
  
  nbrfois = 1;
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(74, 2);
  display.print("km");

  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(52, 18);
  display.print("km/h");

  display.display();
  display.drawRect( 101,  0,  27,  11,  WHITE);  //changer les x et y ( la position)              ligne 1
  display.drawRect( 96,  3,  5,  5,  WHITE);  //si ligne 1 changé de position, faire 2 premieres valeurs -3 et les recopier
  display.display(); 
  }





//**************************************************************************COMPTEUR DE VITESSE******************************************************************************



 
  int diff = abs(analogRead(A1) - valMoy);
  if (diff >= seuil) { //si un aimant pole nord ou un aimant pole sud passe devant le capteur
    if (flagMesure) {
      tempstrouve = millis() - dernierPassage;
      dernierPassage = millis();
      vitesse = (perimetre / (tempstrouve / 1000.0)) * 3.6; //donne la vitesse en km/h grace à v = d/t
      flagMesure = false;     // pour attente cycle suivant
      distance = distance + (perimetre / 1000.0);
      Compteur (distance, vitesse);
    }
  }
  else
  {
    flagMesure = true;  // prêt pour une nouvelle mesure
  } 





//******************************************************************************BATTERIE***********************************************************************************





if((millis() - valeurPrecedente2) > 60000){                                                                               //réactualisation donc calculs du pourcentage batterie toutes les min  
  if ( analogRead(A0)> 868) {
    restant = 100;
  }

  else if ( analogRead(A0)> 861 ) {
    restant = 90;
  }

  else if ( analogRead(A0)> 853 ) {
    restant = 80;
  }

  else if ( analogRead(A0)> 844 ) {
    restant = 70;
  }

  else if ( analogRead(A0)> 835 ) {
    restant = 60;
  }

  else if ( analogRead(A0)> 825 ) {
    restant = 50;
  }

  else if ( analogRead(A0)> 816 ) {
    restant = 40;
  }

  else if ( analogRead(A0)> 806 ) {
    restant = 30;
  }

  else if ( analogRead(A0)> 795 ) {
    restant = 20;
  }

  else if ( analogRead(A0)> 785 ) {
    restant = 10;
  }
  else if ( analogRead(A0)< 785 ) {
    restant = 0;
  } 
  
    display.fillRect( 102,  1,  25,  9,  BLACK);
    display.setTextSize(1);
    display.setTextColor(WHITE);
    display.setCursor(103, 2);
    display.print(restant);
    display.print("%");
    display.display();
}
    
}

Je voudrais ajouter ce code ci :

/* PWM pour moteur à courant continu avec réglage de la souplesse de conduite (2 potentiomètres).
 * On utilise un mosfet n sur le PWM 3 pour commander le moteur
 * Ainsi qu'une poignée accélératrice dont les valeurs min sont 170 et max 870 pour la puissance, et un potentiometre normal pour régler la souplesse de conduite.
  Version 1.4, Incroyables Expériences
  */

void setup() // Boucle d'initialisation.
{
    pinMode(3, OUTPUT);  // Broche 3 réglée comme sortie numérique.
}

float r=0; // Initialisation du rapport cyclique réel à 0.
float s=30; // Initialisation de la souplesse de conduite.
int a=0; // Initialisation du rapport cyclique demandé à 0.
int b=0; // Initialisation de la mémoire du rapport cyclique demandé.
int c=70; // Initialisation du seuil de sécurité (plus il est élevé, moins la sécurité est efficace).

void loop() { // Boucle principale
  a = constrain(a, 170, 870); // Fixation des valeurs extrêmes de l'accélérateur. Cette instruction n’est pas nécessaire si les valeurs de l’accélérateur lues varient bien entre 0 et 1023.
  analogWrite(3,r/1023*254); // Création du PWM.
  a=analogRead(0); // Lecture du rapport cyclique demandé.  (poignée accélératrice)
  s=analogRead(1); // Lecture de la souplesse de conduite demandée.       (potentiometre tableau de bord)

  if(a>b+c){ // Vérification d'une accélération trop brutale (d'origine volontaire ou non).
    digitalWrite(3,LOW); // Arrêt immédiat du moteur.
    while(a>c){ // Attente d'un rapport cyclique très faible pour redémarrer.
      a=analogRead(0); // Lecture continue du rapport cyclique demandé.
    }
  }
  b=a; // Mémorisation du rapport cyclique demandé.

  if(a>r){ // Vérification de la croissance du rapport cyclique demandé.
    delay(20); // Délai responsable de la souplesse de conduite.
    r=r+s/20+2; // Calibrage empirique de la souplesse de conduite.
  }
  if(a<r){ // Vérification de la décroissance du rapport cyclique demandé.
    r=a; // Diminution immédiate du rapport cyclique réel le cas échéant.
  }
  
}

à mon programme mais je ne sais pas comment enlever le while et le delay . Une idée ?

savoriano:
Mieux encore:

if((temps != 0) && (digitalRead(clignotantgauche) == LOW) && (digitalRead(clignotantdroite) == LOW)) {

temps = 0;
}



ça évite de lire les portes la plus part du temps.

Pas besoin de tester si temps est non nul ici. S’il est nul, tu le mettras à zéro de toutes façons.

Pour le while :

Tu fais une lecture de ta pin analogique dans la loop. Lorsque a devient inférieur ou égal à c, tu passes un flag à true.

Dans ta boucle, tu exécutes le reste des instructions uniquement si ton flag est à true.

Pour le delay c'est un peu plus compliqué. Il faut tenir compte du flag. Tu crées un chrono, une variable unsigned long que tu inities avec millis () au début du delay, et tu vérifies que millis ()-chrono passe au dessus de 20 ms. A cet instant ton délai est passé et tu peux exécuter tes instructions. Il te faut un autre flag là aussi, qui reste à false tant que ton délai n'est pas passé et devient true à ce moment. Lorsqu'il est true, tu exécutes les instructions et tu le remets à false.

Mais as-tu vraiment besoin de ce delay ?

Pas besoin de rester si temps est non nul ici. S'il est nul, tu le mettras à zéro de toutes façons.

J'avais fait ça pour éviter de lire les portes clignotantgauche et clignotantdroite à chaque loop.