IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Arduino Discussion :

[nano] Lecture de temps d'un signal et activation d'une sortie en allongeant la durée de ce signal


Sujet :

Arduino

  1. #1
    Candidat au Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Juin 2022
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Corrèze (Limousin)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2022
    Messages : 11
    Points : 3
    Points
    3
    Par défaut [nano] Lecture de temps d'un signal et activation d'une sortie en allongeant la durée de ce signal
    Bonjour à tous.

    Je me prénomme Pierre, j'ai 37 ans, je débute sur arduino, j'ai fait quelque montages simple et j'ai récupéré les cours basiques arduino du collège ou je travaille pour avoir quelques bases.

    J'aurai voulu avoir une explication sur le fonctionnement d'un programme : une version écrite par un ami et une version que j'ai faite moi même

    Si mon post dérange ou si je n'ai pas posté dans la bonne rubrique n'hésitez pas à me le faire savoir et je supprimerai celui-ci.

    Je suis passionné de véhicules ancien et youngtimer et j'ai fabriqué un boitier qui allonge le temps d'injection sur les injections DIGIFANT du groupe volkswagen, qui me permet de corriger la richesse du véhicule.
    Le boitier fonctionne parfaitement sur base d'arduino nano.

    le principe est simple, je lis le signal émit par le calculateur du véhicule, j'ajoute un temps supplémentaire à ce temps d'ouverture pour fermer les injecteurs un peu plus tard. Je peux régler ce temps sur la base d'un pourcentage d'enrichissement avec un potentiomètre et affiner avec une lecture afr large bande pour obtenir le mélange parfait selon l'utilisation (économie, puissance, mix)

    Toutes mes variables et broches sont définies et ma version du programme fonctionne (en partie) sur mon véhicule. Celle écrite par un ami me pose problème, elle obtient pourtant de bon résultats jusqu'a une certaine limite de temps (ou régime ici).

    Je m'explique :

    Première version : sur mon programme, je scrute la broche de signal avec la commande while(digitalread=HIGH) ; je note le temps avec la fonction micros, j'active la broche de sortie. En même temps que je fais ça, je scrute si le signal passe à LOW toujours avec une fonction while, je note le temps quand il passe à LOW, je fais mon calcul de temps additionnel et je ferme ma broche une fois que j'ai ajouté ce temps additionnel au temps normal d'ouverture, et pour cela dans ce premier cas j'utilise la fonction delayMicroseconde.

    Dans cette version, mon montage "fonctionne", c'est a dire que j'arrive à peu près à avoir des résultats escomptés, mais c'est pas parfait et même en augmentant la valeur de temps je reste dans une plage correcte mais pas optimale de richesse dans certaines conditions.

    Deuxième version écrite : à la place d'utiliser delayMicroseconde, il y a une interruption avec la librairie TimerOne (que personnellement je ne maitrise pas encore), donc définition des variables et du Timer1.attacInterrupt pour la fermeture de la broche de sortie. Il y a donc à la place de "delayMicroseconde" un "Timer1.initialise" qui déclenche le compte à rebours, puis l'appel de la fonction et le Timer.stop qui va déclencher la fermeture de la broche de sortie.

    Dans ce cas, j'ai des résultats parfait, jusqu'à ce que le temps total (temps allongé par le programme) déborde sur le signal suivant, c'est à dire que j'ai des coupures, exemple : arrivé à une certain régime, le temps ou la broche qui lit le signal du calculateur est sur LOW est plus court que le temps d'activation de la broche de sortie, et donc il ne prends pas en compte le signal suivant à cause du timer je pense.

    Je ne sais pas si c'est clair et j'en suis désolé

    Je voudrais savoir si il est possible pendant un timer de prendre en compte le signal d'entrée sans couper le signal de sortie et ainsi éviter ces coupures.
    Je me tords l'esprit avec ça depuis un moment en essayant de lui dire que si le temps de coupure est plus court que le temps totale d'ouverture il doit reprendre au début, ou prendre en compte le moment de coupure plutôt que le moment de changement de signal pour faire le calcul mais je n'y arrive pas.


    Si on pouvait me confirmer qu'avec le timer je ne peux pas faire ce que je veux, j'arrêterai de chercher midi à quatorze heure et me contenterai de ma version fonctionnelle imparfaite.

    Sinon, si vous pouviez me mettre sur la voie, ce serait pour moi l'occasion d'en apprendre un peu plus sur l'utilisation du nano.

    voici ce que ça donne sur la partie du code concernée, je n'utilise donc que deux broches du nano:

    Ma version au fonctionnement pas parfait mais fiable depuis 3 mois (manque de richesse sous certaines conditions même si j'augmente le temps, surtout en pleine charge quand le temps d'injection est censé augmenté fortement)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    {
        while (digitalRead(Signal_injecteurs) == HIGH); //on capte le signal du calculateur pour l'ouverture des injecteurs
        debut_ouverture = micros(); //on note l'heure d'ouverture
        digitalWrite(Commande_injecteurs, HIGH);  //on ouvre les injecteur
        digitalWrite(led_int, HIGH);
        while (digitalRead(Signal_injecteurs) == LOW); //le calculateur ferme les injecteurs, on les garde ouvert
        Fermeture_inj = micros();
        T_inj = Fermeture_inj - debut_ouverture; //On calcule le temps d'injection ordonné par le calculateur
        T_sup = float(T_inj * Cor_inj); //On calcule le temps supplémentaire d'ouverture pour application de l'enrichissement
        delayMicroseconds(T_sup);
      digitalWrite(Commande_injecteurs, LOW); //Fermeture des injecteurs
      digitalWrite(led_int, LOW);
      Fermeture_injecteurs = micros();
    }
    La version avec timerone, parfaite jusqu'à mis régime en pleine charge, après il coupe car le timer déborde sur le signal suivant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    {
        while (digitalRead(Signal_injecteurs) == HIGH); 
        debut_ouverture = micros(); 
        digitalWrite(Commande_injecteurs, HIGH);  
        digitalWrite(led_int, HIGH);
        while (digitalRead(Signal_injecteurs) == LOW); 
        Fermeture_inj = micros();
        T_inj = Fermeture_inj - debut_ouverture; 
        T_sup = float(T_inj * Cor_inj); 
        if (Fermeture_injecteurs > debut_ouverture)
        { T_inj = (Fermeture_injecteurs - Fermeture_inj);
          T_sup = float(T_inj * Cor_inj);
        }
        Timer1.initialize(T_sup);
      }
    }
    void ISR_fermeture_injecteurs() {
      Timer1.stop();           
      Fermeture_injecteurs = micros();
      digitalWrite(Commande_injecteurs, LOW); 
      digitalWrite(led_int, LOW);
    }

    Je vous remercie de m'avoir lu.

    Pierre

  2. #2
    Expert confirmé

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 330
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 330
    Points : 4 151
    Points
    4 151
    Par défaut
    Bonjour,

    Si j'ai bien compris, pas sûr, le premier est assimilable à un temporisateur non re-déclenchable tandis que le le second est re-déclenchable.
    Quand il y a recouvrement entre nouvel ordre d'ouverture et l'ouverture prolongée :
    la première solution oubliera la nouvelle ouverture jusqu'à la fin de son propre process puis la détectera en retard ce qui faussera les temps.
    la seconde solution n'oubliera pas la nouvelle ouverture mais réinitialisera le timer en plein milieu de son cycle.
    Nom : Injecteurs 1.png
Affichages : 310
Taille : 32,5 Ko
    Nom : Injecteurs 2.png
Affichages : 311
Taille : 34,1 Ko

    La question est : quel est le comportement souhaité ?

    Salutations
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  3. #3
    Candidat au Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Juin 2022
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Corrèze (Limousin)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2022
    Messages : 11
    Points : 3
    Points
    3
    Par défaut
    Bonjour et merci pour ta réponse.

    Voilà qu'avec des schémas tout est plus clair !

    Le comportement souhaité est dans la solution 2, pas de coupures, et donc une ouverture en continue comme on peut le voir sur la dernière ligne.

    Le code que j'ai posté en deuxième (avec timerone) correspond je pense a cette solution, sauf qu'au lieu de maintenir ouvert, il se coupe jusqu'a ce qu'il retrouve un signal. Je n'ai pas d'explications, j'ai parfois des coupures de plus d'une seconde ! c'est énorme quand on sait que même à haut régime j'ai une impulsion fourni par le calculateur toute les 8 à 10ms en moyenne (6300tr/min comme régulation de régime)

    Quelle serait la bonne approche pour obtenir un résultat comme la solution 2 ?

    Merci encore pour les schémas c'est très clair en visuel

  4. #4
    Expert confirmé

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 330
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 330
    Points : 4 151
    Points
    4 151
    Par défaut
    Bonjour,

    Le problème est que la solution 2 est celle qui devrait résulter de la seconde implémentation. Il y a peut être un problème avec la réinitialisations du timer alors qu'il est en cours d'activité. J'ai supposé qu'il changeait juste la valeur dans le compteur qui continuait son décompte mais cette hypothèse est peut être erronée. Peut être faut il l'arrêter proprement (+ désactiver avant puis réactiver après l'interruption correspondante) avant de le relancer. Une seconde semble indiquer que la réinitialisation ne se passe pas bien et provoque l'arrêt sans relancer la mécanique.

    Je ne connais pas suffisamment les arcanes de cette bibliothèque pour savoir si elle est en cause. Changer un registre qui bouge (volatile par définition) est toujours source potentielle de problèmes. Si on doit changer 2 octets, il peut y avoir une modification entre le chargement du premier et celui du second conduisant à des incohérences.

    Salutations
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  5. #5
    Candidat au Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Juin 2022
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Corrèze (Limousin)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2022
    Messages : 11
    Points : 3
    Points
    3
    Par défaut
    Bonjour, je ne connais pas les rouages de la librairie timerone et cela semble bien trop compliqué pour moi de rentrer dans les détails bien que j'ai regardé quelques documentations sur le net.

    Ce que je constate en réel, c'est qu'effectivement quand le timer est lancé, il "bloque" la carte le temps de sont exécution, comme si elle ne pouvait pas faire autre chose que le décompte de ce timer. Je le vois très bien à le led interne qui reste éteinte le temps que la carte reprenne le controle.

    J'ai essayé de contourner le problème en essayant par exemple de lui dire que si le temps d'ouverture est supérieur à 10ms, il reste ouvert tout le temps, sur le papier ça fonctionne à partir d'un certain régime, mais pas en réel, comme parfois j'ai des des temps d'ouverture qui vont arrivé à cette valeur à bas régime (un démarrage en côte par exemple) et bien ça engorge et cale, car il ouvre tout et du coup rempli le moteur d'essence. Et intégrer dans le code un calcul de régime pour spécifier qu'à partir d'une certain temps ET régime il doit tout ouvrir, d'une part dépasse mes compétence en arduino et demanderait beaucoup de calcul à l'atmega, je ne suis pas certain de la fiabilité par la suite.

    Pierre.

  6. #6
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 711
    Points : 5 390
    Points
    5 390
    Par défaut
    Quelle est la durée typique des impulsions à prolonger? On parle en ms, µs ou en ns ?

    Si ça ne va pas "trop vite", une approche par machine à états pourrait être testée, ce qui permet de ne pas utiliser les timers

    je pense à un code de ce genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    // Les constantes
    const byte pinSignal = 2;             // signal du calculateur pour les Injecteurs : HIGH ouverts, LOW fermés
    const byte pinCommande = 3;           // pin de commande des injecteurs : HIGH on ouvre, LOW on ferme
    const byte pinLed = 13;               // LED témoin
    const byte pinReglage = A0;           // potentiomètre réglage enrichissement
    const double enrichissemntMin = 0.5;  // pourcentage min 50% de temps en plus
    const double enrichissemntMax = 1.5;  // pourcentage max 150% de temps en plus
     
    // les variables
    enum : byte {FERMES, OUVERTS, EN_PROLONGATION, REOUVERTURE} etat = FERMES; // état des injecteurs
    uint32_t momentOuverture;
    uint32_t momentFermeture;
    uint32_t momentReOuverture;
    uint32_t momentReFermeture;
    uint32_t dureeProlongation;
    uint32_t dureeReProlongation;
    double   pourcentageEnrichissement;
     
     
    inline double mapD(double x, double in_min, double in_max, double out_min, double out_max) {
      return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
    }
     
    void commandeOuverture() {
      digitalWrite(pinCommande, HIGH);
      digitalWrite(pinLed, HIGH);
      momentOuverture = micros();
      etat = OUVERTS;
    }
     
    void commandeFermeture() {
      digitalWrite(pinCommande, LOW);
      digitalWrite(pinLed, LOW);
      etat = FERMES;
    }
     
    void gestionInjecteurs() {
      switch (etat) {
        case FERMES:
          if (digitalRead(pinSignal) == HIGH) commandeOuverture();
          break;
     
        case OUVERTS:
          if (digitalRead(pinSignal) == LOW) {  // fermeture
            momentFermeture = micros();
            pourcentageEnrichissement = mapD(analogRead(pinReglage), 0, 1023, enrichissemntMin, enrichissemntMax);
            dureeProlongation = pourcentageEnrichissement * (momentFermeture - momentOuverture);
            etat = EN_PROLONGATION;
          }
          break;
     
        case EN_PROLONGATION:
          if (digitalRead(pinSignal) == HIGH) {  // ré-ouverture pendant la prolongation
            momentReOuverture = micros();
            etat = REOUVERTURE;
          }
     
          if (micros() - momentFermeture >= dureeProlongation) commandeFermeture(); // fin de la prolongation
          break;
     
        case REOUVERTURE:
          if (digitalRead(pinSignal) == LOW) {
            momentReFermeture = micros();
            pourcentageEnrichissement = mapD(analogRead(pinReglage), 0, 1023, enrichissemntMin, enrichissemntMax);
            dureeReProlongation = pourcentageEnrichissement * (momentReFermeture - momentReOuverture);
            if (momentReFermeture - momentFermeture > dureeProlongation - dureeReProlongation) { // faut-il étendre ?
              momentFermeture = momentReFermeture;
              dureeProlongation = dureeReProlongation;
            }
            etat = EN_PROLONGATION;
          }
          break;
      }
    }
     
    void setup() {
      pinMode(pinSignal, INPUT);
      pinMode(pinCommande, OUTPUT); digitalWrite(pinCommande, LOW); // injecteurs fermés
      pinMode(pinLed, OUTPUT);      digitalWrite(pinLed, LOW);      // led éteinte
    }
     
    void loop() {
      gestionInjecteurs();
    }
    absolument non testé

    le principe est le même que dans votre approche sauf qu'on n'utilise pas de delay() qui bloque. On surveille l'état du calculateur et on maintient un état du système.
    la "subtilité" est simplement dans la réouverture alors qu'on est en phase de prolongation. Dans ce cas on attend le refermeture et on regarde si la nouvelle durée prolongée et supérieure à l'ancienne (pour qu'un pic court ne vienne pas annuler une prolongation plus longue attendue précédemment)

    Le code gère la durée d'extension du timing grace à un potentiomètre sur A0 qui fait varier la durée entre enrichissemntMin et enrichissemntMax (50% à 150% de plus)

    Ici le code utilise les fonctions digitalRead(), digitalWrite() et analogRead() qui sont assez lentes. Si le timing est critique alors il faudra passer par les registres des ports. Un encodeur rotatif serait sans doute aussi plus efficace et moins gourmand que de faire une lecture analogique à chaque fois qu'on veut calculer la durée d'extension.


    je ne suis pas un pro du hardware, mais je pense qu'une solution à base de circuit RC (où on peut faire varier la constante de temps) pourrait sans doute faire la même chose en analogique

  7. #7
    Expert confirmé

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 330
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 330
    Points : 4 151
    Points
    4 151
    Par défaut Injection et déjection
    Bonjour Pierre,

    Citation Envoyé par Pierre17dx2 Voir le message
    ...Ce que je constate en réel, c'est qu'effectivement quand le timer est lancé, il "bloque" la carte le temps de son exécution, comme si elle ne pouvait pas faire autre chose que le décompte de ce timer. Je le vois très bien à la led interne qui reste éteinte le temps que la carte reprenne le contrôle...
    C'est contradictoire avec l'usage d'un compteur interne qui indique par interruption la fin de son job.

    Je présume que cela ne se produit que quand il y a recouvrement, c'est à dire quand on réinitialise le timer alors même qu'il est en cours de fonctionnement. C'est pourquoi je proposais d'essayer de l'arrêter avant de le réinitialiser.

    Par ailleurs, il est possible de simuler le comportement du timer avec des mesures de temps (au lieu de retards bloquants).

    Une remarque : le passage par des calculs flottants pour à partir d'entiers obtenir un entier me gène toujours un peu. Surtout dans un processus de contrôle de temps. D'autre part, s'il provient de la lecture d'un potentiomètre, il se présente initialement comme un entier.

    Le code 2 est bizarre : il y a des doublons (mais ce n'est pas la cause du problème).

    Proposition :
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    k = round(Cor_inj * 256);    // ou plus => décalage >> par 8, ici précision de 0.4%
     
    void loop {
       unsigned long T;
       while(digitalRead(Signal_injecteurs)); 
       T = micros(); 
       digitalWrite(Commande_injecteurs, HIGH);  
       digitalWrite(led_int, HIGH);
       while (digitalRead(Signal_injecteurs) == LOW); 
       T = ((micros() - T) * k) >> 8; // Correspond à 256;
       Timer1.stop();
       Timer1.initialize(T);
      }
    }
    void ISR_fermeture_injecteurs() {
       Timer1.stop();           
       digitalWrite(Commande_injecteurs, LOW); 
       digitalWrite(led_int, LOW);
    }

    Pas testé

    Salut
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  8. #8
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 711
    Points : 5 390
    Points
    5 390
    Par défaut
    Citation Envoyé par Guesset Voir le message
    Une remarque : le passage par des calculs flottants pour à partir d'entiers obtenir un entier me gène toujours un peu. Surtout dans un processus de contrôle de temps. D'autre part, s'il provient de la lecture d'un potentiomètre, il se présente initialement comme un entier.
    C'est vrai que le calcul décimal est couteux sur ce type de processeur 8 bit dépourvu de FPU

    Cela dit, c'est difficile de s'en passer si on veut faire du "proportionnel" avec un réglage un peu fin (ie rajouter entre 50% et 150% d'une autre durée par exemple) et pas juste une durée fixe.

    La question à se poser avant de regarder cette optimisation c'est "est-ce que ça fonctionne avec le calcul décimal" et où sont les gros goulots d'étranglement --> si on tient la route, pas la peine d'optimiser cette partie, sinon il faudra effectivement se pencher là dessus (ainsi que virer les fonctions digitalRead(), digitalWrite() et analogRead() qui sont assez lentes comme mentionné précédemment).

  9. #9
    Expert confirmé

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 330
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 330
    Points : 4 151
    Points
    4 151
    Par défaut Petit pas
    Bonjour,

    Je me suis dit que Timer1.initialize() réagissait peut être mal à une valeur nulle (il est possible que cela l'incite à utiliser sa valeur par défaut d'une seconde). Aussi j'ai un peu modifié le code pour éviter de l'appeler dans ce cas.

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    unsigned long k = round(Cor_inj * 256);          // ou > 256 => décalage >> par 8 (précision 0.4%)
     
    void loop {
       unsigned long T;
       while(digitalRead(Signal_injecteurs)); 
       T = micros(); 
       digitalWrite(Commande_injecteurs, HIGH);  
       digitalWrite(led_int, HIGH);
       while (digitalRead(Signal_injecteurs) == LOW); 
       T = ((micros() - T) * k) >> 8; // Correspond à 256;
       if(T > 0) {
          Timer1.stop();
          Timer1.initialize(T);
       }
    }
    void ISR_fermeture_injecteurs() {
       Timer1.stop();
       digitalWrite(Commande_injecteurs, LOW); 
       digitalWrite(led_int, LOW);
    }

    Concernant ce qu'écrit Jay M. J'ai considéré que le facteur était issue d'une numérisation sur 10 bits dont on sait que les 2 bits de poids faibles sont d'une précision toute relative d'où les 256 comme diviseur. Une rotation de 8000 t/mn correspond à une période de 7,5 ms (vraisemblablement à diviser par le nombre de cylindres ?) et alors une précision de 1/256 représente 29 µs (ou 8 µs). Le temps de boucle (loop() ) doit être au moins du même ordre de grandeur. Il induit une incertitude sur le début effectif de l'ordre d'ouverture (une interruption serait mieux). En diminuant ce temps de boucle avec des calculs sur entiers (même 32 bits) on augmente la régularité du processus.
    Mais cela mériterait d'être vérifié.

    Salutations
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  10. #10
    Candidat au Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Juin 2022
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Corrèze (Limousin)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2022
    Messages : 11
    Points : 3
    Points
    3
    Par défaut
    Bonjour à vous,

    Je suis épaté de vos réponses, et il va me falloir plusieurs relectures au calme pour essayer d'intégrer pas mal de choses très techniques pour moi.

    Alors l'ordre de mesure est simple, le calculateur envoie des signaux de 2 à 10ms avec une décimale après la virgule, par contre, le moment de déclenchement doit précis.
    Pour information, je n'ai pas besoin de diviser par le nombre de cylindre, je n'ai qu'un rail, et c'est bien là le problème, si j'avais plusieurs rails d'injecteurs, les temps d'ouverture serait plus espacé, et donc mon programme fonctionnerait probablement sans problèmes.

    Mon régime de coupure est à 6300, mais on va dire 6000, ça ne sert a rien d'aller au délà on a déjà dépasser le point de couple/puissance maxi à 5200, donc un tour toute les 10ms.

    Je n'ai pas spécialement besoin d'avoir plus de 30, voir 35% d'enrichissement, donc de temps supplémentaire.

    J'ai basé ce chiffre (30%) sur mes lectures afr et sur le fait que la pompe a essence a été faite pour le montage d'origine, et qu'en ouvrant plus souvent je pense qu'elle doit atteindre sa limite de débit en pleine charge, si je veux garder la pression correcte pour une bonne pulvérisation, une valeur de 30% qui me parait largement suffisante, et à affiner avec le potentiomètre au roulage.

    Donc dans ma boucle loop, j'avais intégré mon analogread pour lire la valeur de mon potentiomètre et ainsi pouvoir modifier en temps réel l'enrichissement, en bon débutant que je suis...C'est déjà une erreur apparement, ainsi que les digitalread, mais comment capter un signal sans ces fonctions ?

  11. #11
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 711
    Points : 5 390
    Points
    5 390
    Par défaut
    avez vous essayé mon code? (2 à 10ms ça laisse pas mal de temps donc avec un peu de chance on tient bien)

  12. #12
    Candidat au Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Juin 2022
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Corrèze (Limousin)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2022
    Messages : 11
    Points : 3
    Points
    3
    Par défaut
    Citation Envoyé par Jay M Voir le message
    avez vous essayé mon code? (2 à 10ms ça laisse pas mal de temps donc avec un peu de chance on tient bien)
    Non, je n'ai pas le véhicule aujourd'hui, demain sans doute, je testerai et vous donnerez des nouvelles.

    Il ne faut pas que j'oublie de modifier les valeur min et max d'enrichissement avant de téléverser, sinon je vais la noyer

    J'avais une question hardware justement, la marque de la carte influe t'elle sur sa qualité d'exécution ? J'ai lu de tout, mais normalement un atmega238p reste le même sur n'importe quel modèle?

    Actuellement j'ai un nano de marque Elegoo et non arduino, j'ai cramé l'arduino la première fois que j'ai fait le montage sans mettre de résistance en entrée du signal, un collègue professeur de technologie m'a aidé pour le montage hardware du coup.

  13. #13
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 711
    Points : 5 390
    Points
    5 390
    Par défaut
    J'avais une question hardware justement, la marque de la carte influe t'elle sur sa qualité d'exécution ?
    il y a des cartes de plus ou moins bonne qualité sans doute, mais pour ce qui est du 328P ce doit être equivalent. pas de souci à mon avis à-avec votre ELEGOO

    Il ne faut pas que j'oublie de modifier les valeur min et max d'enrichissement avant de téléverser, sinon je vais la noyer
    J'y connais rien donc j'ai mis 50% et 150% complètement au hasard ==> donc oui il faut adapter cela ainsi bien sûr que les N° des pins

  14. #14
    Candidat au Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Juin 2022
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Corrèze (Limousin)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2022
    Messages : 11
    Points : 3
    Points
    3
    Par défaut
    Bonjour,

    Alors j'ai testé votre programme Jay M, et je vous remercie déjà pour ça.

    Le code ne fonctionne pas, la voiture s'est noyé instantanément, car je pense que les commandes ouverture/fermeture doivent être inversé : ma led reste allumé en permanence à la mise de contact, et les impulsions du calculateur font éteindre la led au démarreur : ce qui devrait être l'inverse, la led doit s'allumer uniquement sur les impulsion du calculateur (avec le temps additionnel ajouté a cette impulsion) . Je n'ai bien sûr pas insisté.
    J'ai démonter les bougies et je vais attendre que tout sèche, car là pour le coup elle a bien trop de carburant ça me permet de regarder un peu le reste comme ça, je suis mecanicien auto de formation donc aucun soucis.


    Sinon, j'ai bien pris soin de corriger les valeurs d'enrichissement.
    Les pins sont les même que celles que j'ai utilisées sur mon montage hardware

    J'essaye d'interpréter votre code pour comprendre son fonctionnement en attendant le prochain test, il y a des fonctions qui sont inconnues à mon niveau, je me penche dessus.
    J'avais essayer de faire un code avec la fonction switch/case comme vous avez fait mais sans succès, probablement car j'utilisais toujours le timer et ça ne fonctionnait pas : j'ai lu après qu'une fois le timer lancé, tant qu'il n'a pas la commande timer.stop il bloque le reste.

    Je vais essayer le code de Guesset quand ce sera sec

    Merci encore vous êtes super sympas.

  15. #15
    Expert confirmé

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 330
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 330
    Points : 4 151
    Points
    4 151
    Par défaut
    Bonjour,

    Suite aux problèmes rencontrés par Pierre, j'ai regardé le code de Jay toujours agréable à lire.

    Je n'ai rien vu qui explique les problèmes si ce n'est un doute sur le re-déclenchement.

    Suite à la réflexion de Pierre (chronogramme 2 recherché) j'ai purement supprimé l'état de redéclenchement en considérant qu'un nouvel ordre du calculateur déclenche un nouveau cycle que l'on soit en prolongation ou pas.

    J'ai décalé la lecture du potentiomètre au moment de l'ouverture des injecteurs car c'est là où on a le plus de temps et il me gène un peu d'ajouter du temps de prolongation même si la valeur est 0 (on ajoutera toujours un chouïa à cause du calcul de dT (Temps de prolongation) et le temps de boucle de loop() mais on évite ainsi d'y ajouter le temps d'un analogRead(). Je suis peut être un peu jusqu'au-boutiste . Je considère que 0V sur l'entrée analogique correspond à un temps de prolongation nul (pour tester je conseillerais de commencer avec cette valeur).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    // constantes
    const uint32_t Kmax    = 359;                    // (1023*359) >> 10 = 358 => 358/1024 = 34.9 %
    const byte pinSignal   =   2;                    // signal calculateur : HIGH ouvre, LOW ferme
    const byte pinCommande =   3;                    // pin des injecteurs : HIGH ouvre, LOW ferme
    const byte pinLed      =  13;                    // LED témoin
    const byte pinReglage  =  A0;                    // potentiomètre réglage enrichissement
     
    // variables
    enum : byte {FERMES, OUVERTS, PROLONGES} etat = FERMES; // état des injecteurs
    uint32_t K             =   0;                    // K = 1024 * coef_prolongation
    uint32_t T_open;                                 // Temps repérant l'ordre d'ouverture
    uint32_t dT;                                     // Durée de prolongation
     
    void Ouvrir_Inj() {
      digitalWrite(pinCommande, HIGH);
      T_open = micros();
      digitalWrite(pinLed, HIGH);                    // 0..1023 => K = 0..358 où 358/1024 = 34.9 %
      K      = (uint32_t(analogRead(pinReglage)) * Kmax ) >> 10;
      etat   = OUVERTS;
    }
     
    void setup() {
      pinMode(pinSignal,   INPUT);
      pinMode(pinCommande, OUTPUT);     digitalWrite(pinCommande, LOW);  // injecteurs fermés
      pinMode(pinLed,      OUTPUT);     digitalWrite(pinLed,      LOW);  // led éteinte
    }
     
    void loop() {
       switch (etat) {
       case FERMES:
          if(digitalRead(pinSignal) == HIGH) Ouvrir_Inj();
          break;
       case OUVERTS:
          if(digitalRead(pinSignal) == LOW) {        // ordre de fermeture du calculateur
            uint32_t T = micros(); 
            dT = ((T - T_open) * K) >> 10;           // calcul de la prolongation
            T_open = T;                              // début de la prolongation d'ouverture
            etat = PROLONGES;
          }
          break;
       case PROLONGES:
          if(digitalRead(pinSignal) == HIGH)         // ré-ouverture pendant la prolongation
             Ouvrir_Inj();                           // On débute un nouveau cycle
          else if(micros() - T_open >= dT) { 
              digitalWrite(pinCommande, LOW);        // fin de la prolongation
              digitalWrite(pinLed, LOW);
              etat = FERMES;
          }
       }
    }
    Salutations
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  16. #16
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 711
    Points : 5 390
    Points
    5 390
    Par défaut
    Citation Envoyé par Guesset Voir le message
    Je n'ai rien vu qui explique les problèmes si ce n'est un doute sur le re-déclenchement.
    Qu'est-ce qui vous trouble?

    si c'est l'écriture du test
    if (momentReFermeture - momentFermeture > dureeProlongation - dureeReProlongation) { // faut-il étendre ?

    vous pouvez le dire aussi comme cela: est-ce que le moment de fermeture prévu est avant ou après le nouveau moment de fermeture prévu par le nouvel ordre

    On avait prévu de fermer au moment_initial = momentFermeture + dureeProlongation
    et maintenant on a calculé un moment_nouveau = momentReFermeture + dureeReProlongation

    donc on veut étendre si moment_nouveau > moment_initial
    <=> momentReFermeture + dureeReProlongation > momentFermeture + dureeProlongation
    <=> momentReFermeture - momentFermeture > dureeProlongation - dureeReProlongation

    le passage en soustraction c'est pour gérer proprement le débordement de micros au bout de 71 minutes d'utilisation

    mais on peut effectivement aussi considérer qu'un nouvel ordre du calculateur déclenche un nouveau cycle et on oublie l'ordre précédent.

    Dans ce cas d'ailleurs
    Citation Envoyé par Guesset Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
       case PROLONGES:
          if(digitalRead(pinSignal) == HIGH)         // ré-ouverture pendant la prolongation
             Ouvrir_Inj();                           // On débute un nouveau cycle
    pas la peine de rappeler Ouvrir_Inj() puisque c'est déjà fait il suffit sans doute de noter juste le nouveau temps de départ

  17. #17
    Candidat au Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Juin 2022
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Corrèze (Limousin)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2022
    Messages : 11
    Points : 3
    Points
    3
    Par défaut
    Je viens de constater une chose que je vais préciser, je n'avais pas précisé car mes deux programmes ne le faisaient pas, peut être car j'utilisais un timer ou la fonction delay qui coupaient en fonction du temps et non de l'état de la broche d'entrée. Je tiens à m'excuser pour cet oublie car il est possible que cela induise un non fonctionnement des solutions proposées.

    A la mise du contact du véhicule, les injecteurs sont actionnés pendant un court instant, puis ils sont en circuit ouvert.

    Donc un court instant on a (digitalRead(Signal_injecteurs) == HIGH) puis on passe à (digitalRead(Signal_injecteurs) == LOW).

    Nous avons la même chose en décélération, les injecteurs sont coupés quand on relâche l'accélérateur sur une plage de régime ordonné par le calculateur.

    Je pense que cela pourrait causer les problèmes rencontrés a savoir le noyage de la voiture dès la mise en contact.

    Car sur le dernier programme testé (celui de Guesset), quand je mets le contact, la led interne s'allume, ce qui veut dire que la broche D3 qui ouvre les injecteurs est ouverte en permanence. Mais pourquoi quand le signal (les impulsions) du calculateur arrive pendant la phase de démarrage, cette led ne clignote pas en suivant le signal de la broche D2 ?

    J'ai donc fait un montage rapide sur bredboard pour éviter les montages/démontages sur le véhicule avec un autre nano qui traine (en atmega168) et qui simule un signal de 10ms avec une coupure de 1ms (programme blink dans la bibliothèque d'exemples).
    On va l'appeler nano émetteur, et celui avec le programme d'injection nano récepteur.

    Quand le nano émetteur envoi un signal d'ouverture et fermeture, la led du nano receveur scintille bien et la puissance de la led varie bien en actionnant le potentiomètre, par contre si je coupe le nano émetteur, la led du nano récepteur est allumé pleine puissance en continu.
    Ce qui veut dire qu'en fonctionnement, quand le calculateur va couper les injecteurs en décélération les injecteurs seront grands ouvert.

    Ce qui pose le problème de la gestion, pouvons nous compter sur une fonction switch/case ou faut rester dans les fonction timer ou delay comme je l'avais fait au départ ?

    Car si nous imposons une gestion par le temps et non par l'état il devra obligatoirement couper la sortie (D3) en fonction d'un temp donné n'est-ce pas ?


    Peut être y a t'il d'autres solutions mais encore une fois excusez moi je résonne avec mes maigres compétences de débutant.

    voici mon code de départ fonctionnel, mais ou je perds un peu de richesse quand il y a "recouvrement"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    //Coefficient d'enrichissement maxi
    #define Coeff_max 30 //% d'enrichissement
     
    //Attribution des broches
    #define Signal_injecteurs 2 
    #define Commande_injecteurs 3 
    #define led_int 13
    #define Broche_potentiometre A0 
     
     
    //Variables
    unsigned long debut_ouverture = 0; 
    unsigned long Fermeture_inj = 0;
    unsigned long Fermeture_injecteurs = 0;
    unsigned long T_inj = 0; 
    float T_sup = 0; 
    float Cor_inj;
    int Pot;
    int Potentiometre = 0;
     
     
    void setup() {
      pinMode(Signal_injecteurs, INPUT_PULLUP);
      pinMode(Commande_injecteurs, OUTPUT);
      pinMode(led_int, OUTPUT);
      digitalWrite(led_int, LOW);
      digitalWrite(Commande_injecteurs, LOW);
     
    }
    void loop() {
     
     
      { Potentiometre = analogRead(A0);
        Pot = map(Potentiometre, 0, 1023, 0, Coeff_max);
        Cor_inj = float (Pot) / 100;
      }
      {
        while (digitalRead(Signal_injecteurs) == HIGH); //on capte le signal du calculateur pour l'ouverture des injecteurs
        debut_ouverture = micros(); //on note l'heure d'ouverture
        digitalWrite(Commande_injecteurs, HIGH);  //on ouvre les injecteur
        digitalWrite(led_int, HIGH);
        while (digitalRead(Signal_injecteurs) == LOW); //le calculateur ferme les injecteurs, on les garde ouvert
        Fermeture_inj = micros();
        T_inj = Fermeture_inj - debut_ouverture; //On calcule le temps d'injection ordonné par le calculateur
        T_sup = float(T_inj * Cor_inj); //On calcule le temps supplémentaire d'ouverture pour application de l'enrichissement
        delayMicroseconds(T_sup);
      digitalWrite(Commande_injecteurs, LOW); //Fermeture des injecteurs
      digitalWrite(led_int, LOW);
      Fermeture_injecteurs = micros();
    }
    }

  18. #18
    Expert confirmé

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 330
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 330
    Points : 4 151
    Points
    4 151
    Par défaut
    Bonjour Jay,

    Citation Envoyé par Jay M Voir le message
    ...Qu'est-ce qui vous trouble ? ...
    Sauf erreur de ma part, ça ne semble pas correspondre au comportement précisé par Pierre : redémarrage systématique d'un nouveau cycle sur ordre du calculateur. Or l'arrêt peut encore se manifester.

    Citation Envoyé par Jay M Voir le message
    ...pas la peine de rappeler Ouvrir_Inj() puisque c'est déjà fait il suffit sans doute de noter juste le nouveau temps de départ
    Presque. Il faut aussi actualiser l'état et s'assurer que la position du potentiomètre continue à être lue même quand il y a chevauchement entre prolongation et nouvel ordre du calculateur mais c'est vrai que les 2 digitalWrite() sont alors de trop.

    Salut
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  19. #19
    Expert confirmé

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 330
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 330
    Points : 4 151
    Points
    4 151
    Par défaut Noyade par microcontrôleur
    Bonjour,

    Je ne suis pas sûr de comprendre mais je pense qu'il est possible que ce soit le résultat d'un travail sur état et non sur transition.

    Supposons que le calculateur soit longtemps à HIGH au démarrage par exemple 1 s. Le programme ouvre les injecteurs mais ne satisfait pas à la condition OUVERTS avant 1 s et applique alors un prolongement comme avec une impulsion courte ce qui n'est pas nécessairement pertinent.

    J'ai donc modifié le cas OUVERTS pour qu'il n'applique pas de prolongation si l'impulsion dépasse dTMax = 45 ms (environ 900 / mn) . Cette valeur est certainement à ajuster.
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    // constantes
    const uint32_t Kmax    = 359;                    // (1023*359) >> 10 = 358 => 358/1024 = 34.9 %
    const uint32_t dTmax   = 45000;                  // !!! Temps maxi d'impulsion calculateur 900 t/mn
    const byte pinSignal   =   2;                    // signal calculateur : HIGH ouvre, LOW ferme
    const byte pinCommande =   3;                    // pin des injecteurs : HIGH ouvre, LOW ferme
    const byte pinLed      =  13;                    // LED témoin
    const byte pinReglage  =  A0;                    // potentiomètre réglage enrichissement
     
    // variables
    enum : byte {FERMES, OUVERTS, PROLONGES} etat = FERMES; // état des injecteurs
    uint32_t K             =   0;                    // K = 1024 * coef_prolongation
    uint32_t T_open;                                 // Temps repérant l'ordre d'ouverture
    uint32_t dT;                                     // Durée de prolongation
     
    void Ouvrir_Inj() {
      digitalWrite(pinCommande, HIGH);
      T_open = micros();
      digitalWrite(pinLed, HIGH);                    // 0..1023 => K = 0..358 où 358/1024 = 34.9 %
      K      = (uint32_t(analogRead(pinReglage)) * Kmax ) >> 10;
      etat   = OUVERTS;
    }
     
    void setup() {
      pinMode(pinSignal,   INPUT);
      pinMode(pinCommande, OUTPUT);     digitalWrite(pinCommande, LOW);  // injecteurs fermés
      pinMode(pinLed,      OUTPUT);     digitalWrite(pinLed,      LOW);  // led éteinte
    }
     
    void loop() {
       switch (etat) {
       case FERMES:
          if(digitalRead(pinSignal) == HIGH) Ouvrir_Inj();
          break;
       case OUVERTS:                                 //  !!! Modifié !!!
          if(digitalRead(pinSignal) == HIGH) break;
          uint32_t T = micros(); 
          if(T - T_open  >= dTMax) dT = 0;           // Pas de prolongation si impulsion trop longue
          else dT = ((T - T_open) * K) >> 10;        // sinon calcul de la prolongation
          T_open  = T;                               // début de la prolongation d'ouverture
          etat    = PROLONGES;
       case PROLONGES:
          if(digitalRead(pinSignal) == HIGH)         // ré-ouverture pendant la prolongation
             Ouvrir_Inj();                           // On débute un nouveau cycle
          else if(micros() - T_open >= dT) { 
             digitalWrite(pinCommande, LOW);         // fin de la prolongation
             digitalWrite(pinLed, LOW);
             etat = FERMES;
          }
       }
    }
    Attention, il faut vérifier que le nano émetteur coupé n'a pas un état incertain sur la broche simulant le signal calculateur lequel pourrait être détecté comme un état HIGH ou LOW sans logique prévisible. Mettre une résistance, par exemple de 1k, à la masse sur cette sortie du nano émetteur pour s'assurer d'un état LOW en cas d'arrêt.

    Je ne sais pas si cela résoudra le problème.

    Nota : ce n'est pas mon programme mais celui de Jay que j'ai sauvagement altéré .

    Salut
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  20. #20
    Expert confirmé

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 330
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 330
    Points : 4 151
    Points
    4 151
    Par défaut Clignotant trop rapide
    Bonjour,

    Même au rythme faible de 900 tours par minute la Led clignotera au moins 15 fois par seconde ce qui fait que le clignotement ne se verra pas. La led aura seulement une luminosité apparente plus ou moins forte (moyenne si elle clignote et forte si elle est toujours alimentée).

    Un oscilloscope serait plus apte à révéler ce qui se passe réellement mais il faut en avoir un sous la main...

    Salutations
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Lecture du temps de prise de vue photo
    Par labottine dans le forum C++
    Réponses: 2
    Dernier message: 18/05/2010, 17h04
  2. Création/lecture fichier TEMP, XP vs Vista/7
    Par Razor82 dans le forum Entrée/Sortie
    Réponses: 3
    Dernier message: 16/02/2010, 23h06
  3. lecture en temp réel sur spectre
    Par diaso dans le forum C++
    Réponses: 0
    Dernier message: 02/09/2009, 17h54
  4. Décalage dans le temps d'un signal
    Par matvig dans le forum Signal
    Réponses: 1
    Dernier message: 29/03/2009, 11h24
  5. Réponses: 1
    Dernier message: 08/12/2008, 13h10

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo