Jump to content
  • This is not a forum but a community!

    20100521_GTX_0003.JPGWe all love this mythical and popular car, because we sailed in one being childrens, because someone in the family had one or just because it always made us want it... because it's endearing, whatever we say.
    Its great success is certainly due to the fact that with a simple mechanics, with little or no electronics, it is easy to maintain by yourself without expensive tools, without forgetting that the parts are not expensive and always easy to find. Even today, for some homes, students and people with "little budget", it is a source of great comfort at a lower price: far from car loans and garage mechanics, which are becoming more and more inaccessible. The small engines models (the most common) are very robust and still consume very little, sometimes less than recent "equivalent" cars, which makes it by definition just as ecological, if not even more by the simple fact that we we always use it instead of buying new ones ... At the level of the official technical control, benefiting from its "seniority", it does not undergo the modern standards much too restrictive, the tranquility is assured.
    Today it is still an interesting car for everyday use, especially and clearly from an economic point of view.
    Collectors are also beginning to take an interest in this 30-year-old "granny": restoration, maintenance or refurbishment, repairs, etc ... make it possible to find "newer than new" models for the pleasure of the eyes and to see this French heritage thus safeguarded.
    We have created this community to bring together all those who are interested and who wish to take part in this adventure to preserve their Renault Super 5, whether by maintenance, repair or restoration: you will find here all useful information and tips on these topics.

    The forum is freely accessible in its entirety: there is no need to contribute, buy, neither pay anything to integrate the community and participate.
    To be able to ask questions and share your interest, all you have to do is register and present yourself properly!
    You do not have to have a Super 5: an interest in auto mechanics is enough

    Welcome !

    (This message disappears if you register into the forum)

    [Translated from french using GoogleTranslation tool]

     

Régulateur de vitesse commandé par Arduino


totojest
 Share

Recommended Posts

Le 09/10/2022 à 17:47, totojest a dit :

Nouveau schéma électronique mis à jour, merci @Tatick pour tes infos :) (Ce n'est toujours pas la version finale, qui prendra en compte le pont pour le compte tours)

Recoucou Totojest, où en es-tu de ton projet qui m'a semblé bien intéressant, même si je ne comprends pas grand chose dans la partie Arduino... Le problème, c'est trop petit pour moi pour lire  et j'ai pas réussi à voir le lien, sinon j'aurais fait l'effort d'essayer d'y comprendre quek chose... As-tu abandonné l'idée ?

 

Link to comment
Share on other sites

Salut @Tatick, l'idée n'est pas du tout abandonnée, mais je n'ai pas beaucoup de temps en ce moment pour avancer. J'ai simplement tiré un cable pour le signal compte tours, j'ai monté (à tour de rôle) une résistance 100k et 47k en parallèle du compte tours, et apparemment, je n'ai aucune modification du signal du compte tours. Puis j'ai remplacé la résistance par un potentiomètre 22k, j'ai pu descendre à presque 0 sans que la valeur au compte tours ne change, mais le potard s'est mis à fumer, je n'ai donc pas pu déterminer la valeur de résistance minimale que je pouvais mettre en parallèle du compte tours... Je pense donc faire mon diviseur de tension à partir de deux résistances de 47k pour mes tests suivants...

 

Là c'est déménagement, et beaucoup de préparation pour du boulot... Je ne pense pas pouvoir me repencher sur le sujet avant mi décembre...

Link to comment
Share on other sites

Le 10/10/2022 à 08:08, Zorro_X a dit :

Ton diagramme fonctionnel n'est pas évident à lire puisque visiblement t'utilises ta propre nomenclature.

 

Où peut-on trouver les nomenclatures pour réaliser des diagrammes fonctionnels standards ?

Link to comment
Share on other sites

Le 10/10/2022 à 00:17, totojest a dit :

Bon, en fait, pour qu'il soit plus lisible, il faut encore une fois le télécharger (cette fois c'est plus léger, 24 ko): Lien valable 15 jours

Flûte, je n'avais pas coché "suivre le sujet" 😲

Pourrais-tu remettre le lien pour accéder à une image lisible, stp ?😉

PS : je viens de voir que tu avais aussi mis un lien le 7 Octobre .....

Edited by repar2000-r9
Link to comment
Share on other sites

Le 06/10/2022 à 21:47, totojest a dit :

Moi c'est sur que je vais mettre une vitesse de rotation moteur (par exemple 2000 tours), et que je ne pourrais pas maintenir la même vitesse si je suis en 4ème (environ 75 km/h sur l'Espace) ou 5ème (90 km/h). Mais je m'en fiche, ce qui m'intéresse, c'est de ne plus avoir à fatiguer ma jambe droite...

Cet inconvénient peut même être utilisé comme un avantage :

si tu cales à 90 en 5ème, soit disons 2500 rpm, en troisième ça donnera 50 , environ.

Ce qui peut être utile en environnement urbain.

 

Mais en fait, ce serait plutôt une fonction "limiteur de vitesse" qui serait utile, pour ne pas avoir à se soucier de regarder le  compteur.

Pour ma part, j'apprécie l'Automatic dans les "zones 30" :

au lieu de m’obséder avec le compteur ( dont, en plus, l'aiguille bagotte ) j'arrête d'accélérer dès que la 2ème passe, soit environ 30 km/h

 

Edited by repar2000-r9
Link to comment
Share on other sites

Le 01/11/2022 à 12:28, totojest a dit :

Puis j'ai remplacé la résistance par un potentiomètre 22k, j'ai pu descendre à presque 0 sans que la valeur au compte tours ne change, mais le potard s'est mis à fumer, je n'ai donc pas pu déterminer la valeur de résistance minimale

 

Tu es donc allé presque au court-circuit ! Tu as du bol de n’avoir rien cramé (il est préférable de mettre une résistance de butée sur un potar…),  mais cette expérience prouve que le circuit du capteur est largement amplifié en courant, proche d’une basse impédance de sortie et passant par un buffer de protection.  D’où ton expérience prouve que tu peux tirer ton signal sous environ 3  V sans problème.

 

Tu dis 8 V sur le signal carré, tu en veux 3.  Avec 33K (vers chaud) et 22K (vers froid), tu vas tirer 3.2 V, sous  0,15 milliamps, ça doit suffire pour commuter une entrée Arduino. Mais ça suffirait aussi pour saturer une base de tr à travers quelques K pour un optocoupleur de sécurité au cas zou...

Donc ta mesure kamikaze donne la réponse !

De mon coté j’ai réfléchi pour concevoir un capteur pour compter les tours du cardan droit sur une boite JB5. Pas avec des aimants (un capteur effet Hall serait simple, hélas !) pour ne pas récupérer de saloperies en ferraille autour du cardan… Je me dirige plutôt vers un capteur à induction et mise en forme des créneaux pour avoir des impulsions de longueur constantes quelque soit le rapport cyclique. Le fait est que selon la vitesse de la voiture, ce rapport cyclique se modifie énormément, et de plus en induction il sera sinusoïdal et d'amplitude variable aussi, il faut donc le mettre en forme, ce qui n’est pas compliqué. Cela dit, je ne sais pas si Arduino gère ce type de question sur ses entrées.

J’imagine huit impulsions par tour, par exemple huit petits plots en acier doux sur un collier Colson collé au cardan prés de la boite... Soit environ 80 hz à 50 km/h, 168 hz à 110 km/h pour un développement de roue de Super 5 autour d’1,5 m.

Mais moi aussi je suis bloqué en ce moment et je verrai ça  en décembre. Bon courage pour ton déménagement.

Link to comment
Share on other sites

  • 5 months later...

Le projet a un peu repris ces derniers temps, je suis en train de finaliser une installation "V0" pour laquelle je pensais me passer de l'Arduino, mais qui finalement, faute de matériel disponible suffisant et d'une échéance qui se rapproche pour mon test, va aussi accélérer l'installation de la partie "calculateur".

 

Aussi, côté matériel, j'ai donc un Arduino Nano chinois (le même que j'utilise pour mes commandes d'autoradio), une platine 4 relais (même si pour le moment j'en ai besoin que de 3), le moteur/electromaimant en place sur le cable d'accélérateur (voir photo plus bas pour le montage), la commande 4 boutons, un relais de sécurité pour désactiver le régulateur si je freine, et un interrupteur d'alimentation générale pour le 12V (le 5V sera tout le temps fourni, et utilisé uniquement pour l'Arduino et l'alimentation de la platine relais).

 

Ce montage "V0" a juste pour but de commander le servomoteur, il n'y a encore aucun asservissement de la vitesse. Il servira donc juste à maintenir une pression sur l'accélérateur en tirant sur le cable:

IMG_0012.jpg.7d2eb6da907dfddb616effd45989afa1.jpg

 

Et voici le code, basé sur celui que j'avais déjà fait (mais pas partagé encore). Cette version "light" m'a permis de déceler quelques lacunes dans mon code initial, comme quoi il vaut mieux commencer par du simple des fois au lieu de se lancer tête baissée dans un projet qu'on veut déjà bien abouti :laugh:

 

//#####################################################################
//## Déclaration des variables d'environnement                       ##
//#####################################################################
#include <EEPROM.h>  // Bibliothèque mémoire
   
#define TEMPS_MAINTIENLONG 1500                                       // Temps de maintien en appui long
#define TEMPS_REMISEZERO 30000                                        // Durée de remise à zéro

//----------------------------------------------------------------------------------------------------------------------------
// Déclaration des raccordements digitaux sur la carte
//----------------------------------------------------------------------------------------------------------------------------
int cmdelectroaimant = 2;  // Commande relais électroaimant de sécurité
int cmdacceleration  = 3;  // Commande relais accélération
int cmddeceleration  = 4;  // Commande relais décélération 
int btnplus          = 5;  // Bouton +
int btnmoins         = 6;  // Bouton -
int btnmemo          = 12; // Bouton MEMO 
int btnoff           = 7;  // Bouton OFF (relais des pédales de frein et d'embrayage + bouton Off de la commande au volant)

//----------------------------------------------------------------------------------------------------------------------------
// Structure permettant de définir les propriétés d'un bouton
//----------------------------------------------------------------------------------------------------------------------------
struct Bouton {
  int entreeDigitale;           // Entrée digitale où le bouton est connecté
  bool boutonAppuye;            // Etat du bouton
  unsigned long date;           // Date à laquelle on a commencé à appuyer sur le bouton 
};

//----------------------------------------------------------------------------------------------------------------------------
// Définition des boutons
//----------------------------------------------------------------------------------------------------------------------------
Bouton off;   // Bouton OFF (relais des pédales de frein et d'embrayage + bouton Off de la commande au volant)
Bouton memo;  // Définition du bouton de mémorisation vitesse
Bouton plus;  // Définition du bouton +
Bouton moins; // Définition du bouton -

//----------------------------------------------------------------------------------------------------------------------------
// Définition des fonctions qu'on associe aux boutons
//----------------------------------------------------------------------------------------------------------------------------
enum FonctionBouton {
  RIEN,      // Fontion neutre, il n'y a rien à faire
  OFF,       // Fonction OFF
  MEMO,      // Fonction mémorisation vitesse
  MEMOLONG,  // Fonction associée à l'appui long sur le bouton mémorisation
  PLUS,      // Fonction +
  PLUSLONG,  // Fonction appui long sur +
  MOINS,     // Fonction -
  MOINSLONG, // Fonction appui long sur -
};

//----------------------------------------------------------------------------------------------------------------------------
// Type énuméré permettant de définir les états des boutons
//----------------------------------------------------------------------------------------------------------------------------
enum EtatBouton {
  ETAT_RELACHE,           // Le bouton est relâché
  ETAT_APPUYE,            // Le bouton est appuyé
  MAINTIEN_LONG,          // Le bouton est maintenu appuyé
};

//----------------------------------------------------------------------------------------------------------------------------
// Déclaration des variables globales utilisées dans le code
//----------------------------------------------------------------------------------------------------------------------------
bool erreur = true;                       // Variable d'erreur
bool erreurmemo = false;                  // Variable d'erreur pour le bouton MEMO et empêcher le reset automatique s'il est détecté bloqué à l'initialisation
int vitessemini = 1500;                   // Vitesse minimum pour l'activation du régulateur de vitesse
int vitessememoire = 0;                   // Vitesse mise en mémoire pour la régulation
String vitesseaffichage = String(0);      // Vitesse convertie en type String pour l'affichage
int pasvitesse = 50;                      // Pas avec lequel on incrémente ou diminue la valeur de vitesse
int gdpasvitesse = 250;                   // Pas avec lequel on incrémente ou diminue la valeur de vitesse lors d'appui long
int margevitesse = 5;                     // Marge de vitesse permettant de ne pas trop solliciter la régulation de vitesse
int positionservomini = 5;                // Position minimale du servomoteur
int positionservomax = 97;                // Position maximale du servomoteur
int positionservo1 = 200;                 // Position initiale du servomoteur utilisée pour la fonction de vérification
int chronoservo = 0;                      // Chronomètre pour évaluer les mouvements du servomoteur
bool regulation = false;                  // Régulateur actif ou non
bool etatantelectro = false;              // Etat antérieur de l'électroaimant (pour éviter le clignotement des dessins play et pause)
bool cmdeoff = true;                      // Flag de vérification de l'état OFF pour ne pas exécuter le cas "default" dans le loop quand OFF est ouvert
String commande = "commande";
String appuyee = "appuyee";
String espace = " ";
String txtvitesse = "Vitesse";
String insuffisante = "insuff";
String txtmemo = "Memo";
String txtoff = "Off";
String txtplus = "Plus";
String txtmoins = "Moins";

//#####################################################################
//## Déclaration des fonctions                                       ##
//#####################################################################

//----------------------------------------------------------------------------------------------------------------------------
// Fonction "etatDuBouton" qui gère les états des boutons (revoie un des états contenus dans la variable énumérée EtatBouton)
//----------------------------------------------------------------------------------------------------------------------------
EtatBouton etatDuBouton (Bouton *boutonATraiter) {
  EtatBouton etat = ETAT_RELACHE;                                              // Valeur qui sera renvoyée comme résultat de cette fonction, par défaut ETAT_RELACHE
  bool etatSignal = !digitalRead(boutonATraiter->entreeDigitale);              // Lire l'état de l'entrée dans une nouvelle variable temporaire

  if ( etatSignal ) {                                                          // Si le bouton semble avoir été appuyé (pas de signal, ou signal = 0/false)
    if (!boutonATraiter->boutonAppuye) {                                       // Si c'est la première fois que le bouton est détecté appuyé, on lance un chrono
      boutonATraiter->date = millis();
    }
    boutonATraiter->boutonAppuye = true;                                       // On attribue au bouton l'état appuyé
    if (millis () - boutonATraiter->date > TEMPS_MAINTIENLONG) {               // Si le bouton est appuyé depuis plus du temps défini
      etat = MAINTIEN_LONG;                                                    // Renvoyer l'état appui long
    }
    else {                                                                     // Sinon on est sur un simple appui
      etat = ETAT_APPUYE;                                                      // Renvoyer l'état appuyé
    }
  }
  else {                                                                       // Si le bouton n'est pas appuyé
    boutonATraiter->boutonAppuye = false;                                      // On attribue au bouton l'état non appuyé
    etat = ETAT_RELACHE;                                                       // Renvoyer l'état relaché
  }
  return etat;                                                                 // Renvoyer l'état du bouton en sortie de fonction
}

//----------------------------------------------------------------------------------------------------------------------------
// Fonction "lectureCommande" qui contrôle les instructions données par le bouton multiposition
//----------------------------------------------------------------------------------------------------------------------------
FonctionBouton lectureCommande () {
  FonctionBouton fonction = RIEN; // Fonction renvoyée (par défaut: RIEN)
  // Lecture des états des boutons
  EtatBouton etatoff   = etatDuBouton( &off );
  EtatBouton etatmemo  = etatDuBouton( &memo );
  EtatBouton etatplus  = etatDuBouton( &plus );
  EtatBouton etatmoins = etatDuBouton( &moins );
  // Définition des fonctions en fonction de l'état des boutons
  // Bouton Off
  switch ( etatoff ) {
    case ETAT_RELACHE : {
      Serial.println(F("Bouton Off ouvert"));
        fonction = OFF;
      }
      break;

    case ETAT_APPUYE : {
      Serial.println(F("Bouton Off fermé"));
        ;
      }
      break;

    case MAINTIEN_LONG : {
        Serial.println("Bouton Off fermé long");
        ;
      }
      break;

    default : {
        erreur = true; // Mettre en erreur, le bouton doit forcément être dans un des états précédents
        Serial.println(F("Erreur sur bouton Off "));
      }
  }
  
  // Bouton Memo
    switch ( etatmemo ) {
    case ETAT_RELACHE : {
        ; // Ne rien retourner
      }
      break;

    case ETAT_APPUYE : {
        Serial.println(F("Bouton Memo appuyé"));
        fonction = MEMO;
      }
      break;

    case MAINTIEN_LONG : {
        Serial.println("Bouton Memo appuyé long");
        fonction = MEMOLONG;
      }
      break;

    default : {
        erreur = true; // Mettre en erreur, le bouton doit forcément être dans un des états précédents
        Serial.println(F("Erreur sur bouton Memo "));
      }
  }

    // Bouton Plus
    switch ( etatplus ) {
    case ETAT_RELACHE : {
        ; // Ne rien retourner
      }
      break;

    case ETAT_APPUYE : {
        Serial.println(F("Bouton + appuyé"));
        fonction = PLUS;
      }
      break;

    case MAINTIEN_LONG : {
        Serial.println("Bouton + appuyé long");
        fonction = PLUS;
      }
      break;

    default : {
        erreur = true; // Mettre en erreur, le bouton doit forcément être dans un des états précédents
        Serial.println(F("Erreur sur bouton + "));
      }
  }

    // Bouton Moins
    switch ( etatmoins ) {
    case ETAT_RELACHE : {
        ; // Ne rien retourner
      }
      break;

    case ETAT_APPUYE : {
        Serial.println(F("Bouton - appuyé"));
        fonction = MOINS;
      }
      break;

    case MAINTIEN_LONG : {
        Serial.println("Bouton - appuyé long");
        fonction = MOINS;
      }
      break;

    default : {
        erreur = true; // Mettre en erreur, le bouton doit forcément être dans un des états précédents
        Serial.println(F("Erreur sur bouton - "));
      }
  }
  return fonction;
}

//#####################################################################
//## Initialisation du circuit (fonction setup)                      ##
//#####################################################################

void setup() {
  Serial.begin(9600);                    // Ouvre le port série
  
  // Déclaration des pins:
  // pour les boutons
  pinMode(btnoff, INPUT_PULLUP);     // On déclare le pin "btnoff" comme un pin d'entrée "pullup"
  pinMode(btnmemo, INPUT_PULLUP);    // On déclare le pin "btnmemo" comme un pin d'entrée "pullup"
  pinMode(btnplus, INPUT_PULLUP);    // On déclare le pin "btnplus" comme un pin d'entrée "pullup"
  pinMode(btnmoins, INPUT_PULLUP);   // On déclare le pin "btnmoins" comme un pin d'entrée "pullup"
  off.entreeDigitale   = btnoff;
  memo.entreeDigitale  = btnmemo;
  plus.entreeDigitale  = btnplus;
  moins.entreeDigitale = btnmoins;
  // pour les relais
  pinMode(cmdelectroaimant, OUTPUT);
  pinMode(cmdacceleration, OUTPUT);
  pinMode(cmddeceleration, OUTPUT);
  // pour l'asservissement du servomoteur et le capteur de vitesse: pas besoin, ce sont des entrées analogiques
  Serial.println(F("Pins initialisés"));

  // Initialisation erreur
  erreur = false;

  // Initialisation commandes
  digitalWrite(cmdelectroaimant, HIGH);
  digitalWrite(cmdacceleration, HIGH);
  digitalWrite(cmddeceleration, HIGH);
 
  // Commandes:
  // Vérification de la commande MEMO
  if (!digitalRead (memo.entreeDigitale)){
    erreurmemo = true; // Le bouton MEMO détecté "bloqué" au démarrage doit pouvoir empêcher la réinitialisation dans le loop
    Serial.println(F("Lecture initialisation: MEMO"));
    delay (5000); // On prend 5 secondes pour lire le message (et tant pis si on stoppe le code, on n'est qu'au stade de l'initialisation, ce n'est pas grave)
    // Ne pas laisser le régulateur fonctionner si ce bouton est appuyé au départ
    erreur = true;
  }
  // Vérification de la commande MOINS
  if (!digitalRead (moins.entreeDigitale)){
    Serial.println(F("Lecture initialisation: MOINS"));
    delay (5000); // On prend 5 secondes pour lire le message (et tant pis si on stoppe le code, on n'est qu'au stade de l'initialisation, ce n'est pas grave)
    // Ne pas laisser le régulateur fonctionner si ce bouton est appuyé au départ
    erreur = true;
  }
  // Vérification de la commande PLUS
  if (!digitalRead (plus.entreeDigitale)){
    Serial.println(F("Lecture initialisation: PLUS"));
    delay (5000); // On prend 5 secondes pour lire le message (et tant pis si on stoppe le code, on n'est qu'au stade de l'initialisation, ce n'est pas grave)
    // Ne pas laisser le régulateur fonctionner si ce bouton est appuyé au départ
    erreur = true;
  }
  // Vérification de la commande OFF (on ne bloque pas celle là, car on peut rester appuyé sur le frein ou l'embrayage, par contre on met juste un message à l'écran)
  if (digitalRead (off.entreeDigitale)){
    Serial.println(F("Lecture initialisation: OFF"));
    delay (2000); // On prend 2 secondes pour lire le message (et tant pis si on stoppe le code, on n'est qu'au stade de l'initialisation, ce n'est pas grave)
  }
  // Si on n'a pas eu d'erreur (dans les if précédents) et qu'on n'a pas appuyé sur OFF, on affiche qu'aucune commande n'a été appuyée
  else if (!erreur) {
    Serial.println(F("Lecture initialisation: RIEN"));
    delay (2000); // On prend 2 secondes pour lire le message (et tant pis si on stoppe le code, on n'est qu'au stade de l'initialisation, ce n'est pas grave)
  }
    
  // Si pas d'erreur à l'initialisation, on informe que tout est prêt
  if (!erreur) {
    Serial.println(F("Fin initialisation"));
  }
}


//#####################################################################
//## Fonction loop                                                   ##
//#####################################################################

void loop() {
  if (!erreur){
    
      switch (lectureCommande ()){
        case MEMO : {
          cmdeoff = false;
          // Rien
        }
        break;
        
        case MEMOLONG : {
          cmdeoff = false;
          // Rien
        }
        break;
        
        case PLUS : {
          Serial.println(F("Loop: PLUS"));
          digitalWrite(cmdacceleration, LOW);
          digitalWrite(cmddeceleration, HIGH);
          digitalWrite(cmdelectroaimant, LOW);
          cmdeoff = false;
        }
        break;
        
        case MOINS : {
          Serial.println(F("Loop: MOINS"));
          digitalWrite(cmdacceleration, HIGH);
          digitalWrite(cmddeceleration, LOW);
          digitalWrite(cmdelectroaimant, LOW);
          cmdeoff = false;
        }
        break;
        
        case OFF : {
          Serial.println(F("Loop: OFF"));
          digitalWrite(cmdacceleration, HIGH);
          digitalWrite(cmddeceleration, HIGH);
          digitalWrite(cmdelectroaimant, HIGH);
          cmdeoff = true;
          delay (1000); // Histoire d'être sur que l'electroaimant soit bien désactivé

        }
        
        default : {
          if (!cmdeoff) {
            Serial.println(F("Loop: ON"));
            digitalWrite(cmdacceleration, HIGH);
            digitalWrite(cmddeceleration, HIGH);
            digitalWrite(cmdelectroaimant, LOW);
          }
          cmdeoff = false;
        }
      }
      
    
  }
  else { // En cas d'erreur relevée, on stoppe le régulateur
    Serial.println(F("Arrêt d'Urgence dans le loop"));
    // Si on appuie longtemps sur MEMO, on peut réinitialiser le régulateur
    if (!erreurmemo){    // Si le bouton n'était pas bloqué à l'initalisation, on autorise la réinitialisation
      if (lectureCommande () == MEMOLONG) {
        delay (5000);
        asm volatile("jmp 0x00");  // Réinitialisation depuis le début
      }
    }
  }
}

Pour info, mes boutons seront couplés à des condensateurs pour éviter les rebonds et ne pas avoir à coder le filtrage comme suggéré par @Zorro_X dans son blog. Je trouve que ça rend leur utilisation plus réactive ainsi. J'ai aussi laissé trainer des "delay", exprès pour stopper le code, soit dans des endroits critiques (comme l'arrêt forcé, ou le reset quand un soucis est détecté à l'initialisation), soit pour permettre de prendre le temps de lire quelque chose (dans l'autre version de mon code, j'utilise un écran).

 

Sur le banc d'essai, ça fonctionne bien, je suis confiant pour le monter tel quel dans la voiture et le tester en condition réelle. Les critiques constructives sur ce "premier jet" sont les bienvenues :)

  • Like 1
Link to comment
Share on other sites

il y a 43 minutes, totojest a dit :

mes boutons seront couplés à des condensateurs pour éviter les rebonds et ne pas avoir à coder le filtrage

 

t'as pris quoi comme condo pour ça ? t'as déjà testé ?

Link to comment
Share on other sites

C'est un condensateur céramique classique monté en parallèle avec le bouton, calibré à 10nF (mais je crois que la valeur influe peu) et ça fonctionne très bien sur mon petit banc de test aussi bien avec ce code qu'avec le code "plus abouti". Je n'ai pas eu de faux déclenchement non plus, principalement lors de la phase d'initialisation. Ca a l'air bon :)

 

Je ferai une petite vidéo de démonstration une fois que je l'aurais monté. Je dois encore faire le cablage, et retrouver dans la voiture où j'ai bien pu laisser la prise d'alimentation 5V que j'avais réservée pour ce montage :laugh:

Link to comment
Share on other sites

  • 7 months later...

Quelques mois plus tard, on s'y repenche encore...

Le 20/04/2023 à 19:42, Zorro_X a dit :

ok, t'es quand même en pull-up ?

Oui, j'ai aussi des résistances de pull up :) Un sacré bordel à intégrer sans PCB... Ce serait bien plus propre si j'en faisais un, mais j'ai un peu la flemme (je ne l'aurais peut être pas si un jour je dois changer l'Arduino parce qu'il aurait cramé ou que sais-je...) :nosweat: Pour rappel, l'électronique est comme ceci aujourd'hui :laugh: 

IMG_1809.JPG.6019265a9e3e08018d073fed8229e837.JPG

 

Mais là, je voulais revenir au schéma électrique et proposer une version qui s'approcherait de la version finale, en prenant en compte les composants que j'ai mis en place:

182514047_Schemaregulateur3.thumb.jpg.4ed21761484619aa9ef96fc66f524272.jpg

 

Donc, par rapport à la version précédente, il y a la réattribution de pins sur l'Arduino, l'intégration de la platine relais (au lieu des semiconducteurs) qui est un outil tout prêt et pas si onéreux, et la mise en place du pont diviseur de tension en sortie du compte tours calculé en fonction des valeurs fournies par @Tatick dans la page précédente (à savoir 1,8 V et 8 mA) et de façon à ne pas avoir à amplifier le signal pour l'optocoupleur. Il faudrait juste que je teste avant de mettre ça en place qu'une résistance de 1k ne chauffe pas trop en parallèle du compte tours... Sinon il faudra monter les valeurs et mettre en place un circuit d'amplification pour l'optocoupleur... Ou juste brancher l'Arduino en direct :ki:

  • Like 1
Link to comment
Share on other sites

  • 2 weeks later...

Encore une petite mise à jour sur le sujet, une petite erreur sur le branchement de l'optocoupleur qui visiblement a quand même besoin d'une tension sur la sortie. J'avais aussi inversé les broches de l’émetteur et du collecteur (3 et 4). Enfin j'ai rajouté un potard pour régler la vitesse du moteur pour l'accélération et décélération (j'aurais pu le faire électroniquement, mais j'ai pas le niveau :nosweat:)

763567083_SchemaArduino3.1.thumb.jpg.cbd70d435afb08a67214e2bb0cbaf8fa.jpg

 

Prochaine étape: ce sera de tester l'optocoupleur avec un Arduino de test et voir si j'arrive à récupérer un signal avec le montage que j'ai fait. J'ai un optocoupleur de récupération qui provient d'une alimentation secteur, j'espère que ça ira... D'ailleurs voici le montage électronique (les résistances sont isolées sous la gaine thermo). Ca fait brouillon, je suis d'accord, et si ça marche peut être que je ferais le montage sur PCB (oui, j'en ai déjà parlé, mais sur des plaquettes à faire soi-même):

IMG_1829.jpg.8f3671679c246b436222256e85874e4f.jpg

 

Et sur le reste du circuit avec l'ajout du potard:

IMG_1830.jpg.26bd325571e2bd7cc01af79e9e0cea24.jpg

  • Like 2
  • Well done! 1
Link to comment
Share on other sites

  • 5 months later...

Le projet avance tout doucement... Et je suis un peu revenu en arrière pour ne pas trop mettre la charrue avant les boeufs. J'avais des déconnections intempestives à chaque fois que je lâchais la commande d'accélération, je ne pouvais pas décélérer, j'avais une fuite massive de courant quand je voulais déboguer (donc en alimentant l'Arduino avec le 5V de l'ordi)... Bref, beaucoup de choses à revoir.

 

Donc là, j'en suis à un truc beaucoup plus basique: je veux juste maintenir la pression sur l'accélérateur, sans asservissement quelconque, ni autre affichage que la console série. Je suis enfin arrivé à un code qui, sur le bureau du moins, a l'air beaucoup plus stable et à partir duquel je vais me baser pour la suite.

 

Mais commençons par le plus "joli" pour ceux qui n'ont pas envie d'aller dans le technique, voici le montage tel qu'il est aujourd'hui. Toutes les fonctionnalités futures sont déjà en place, mais pas activées pour le moment. On retrouver l'Arduino monté sur un "PCB" maison, interchangeable si j'ai le malheur de le cramer. Il y a tout le faisceau, et la commande au volant, et 3 relais pour les commandes de l'électroaimant, l'accélération et la décélération, le convertisseur 12V - 5V et un interrupteur qui me permet de la sortir du circuit quand je veux déboguer (puisque c'est elle qui me drainait un courant de malade et faisait surchauffer l'Arduino, un miracle qu'il n'ait pas déjà cramé...)

IMG_0072.JPG.9f48b1c1e1ad28f0de69bcf56eb05905.JPG

 

IMG_0073.JPG.14aea09c5fbb2198f18a23fafa050b92.JPG

 

IMG_0075.JPG.fac7c4499f4221946fa3b33f861f744a.JPG

 

Et voici la petite boite dans laquelle j'avais mis tout ça (j'avais tout sorti pour essayer de trouver la raison de mon court-jus, je vais pouvoir tout remettre dedans).

IMG_0074.JPG.123a30195dc053a7e572479c77119aee.JPG

 

Maintenant pour ceux que ça intéresse, voici le schéma complet tel qu'il est actuellement, je n'ai juste pas représenté le convertisseur 12-5V ni l'interrupteur qui va avec. Les différences avec le précédent: les relais qui sont à présent individuels et le positionnement d'une résistance qui devait servir à ralentir la rotation du moteur de commande (j'avais mis un potentiomètre, mais ça ne marchait pas, le moteur perdait trop en couple et donc se bloquait).

Schema4.thumb.jpg.294d56f4a5a0bea18f6fea2088f6192e.jpg

 

Et enfin, le code du jour, avant de l'avoir testé dans la voiture en conditions réelles (j'ai des variables déclarées au début qui sont en trop, mais que je devrais utiliser dans les évolutions du code):

//#####################################################################
//## Déclaration des variables d'environnement                       ##
//#####################################################################
#include <EEPROM.h>  // Bibliothèque mémoire
   
#define TEMPS_MAINTIENLONG 1500                                       // Temps de maintien en appui long
#define TEMPS_REMISEZERO 30000                                        // Durée de remise à zéro
#define CMDELECTROAIMANT 2                                            // Commande relais électroaimant de sécurité
#define CMDACCELERATION 3                                             // Commande relais accélération
#define CMDDECELERATION 4                                             // Commande relais décélération 
#define BTNPLUS 5                                                     // Bouton +
#define BTNMOINS 6                                                    // Bouton -
#define BTNOFF 7                                                      // Bouton OFF (relais des pédales de frein et d'embrayage + bouton Off de la commande au volant)
#define BTNMEMO 12                                                    // Bouton MEMO

//----------------------------------------------------------------------------------------------------------------------------
// Structure permettant de définir les propriétés d'un bouton
//----------------------------------------------------------------------------------------------------------------------------
struct Bouton {
  int entreeDigitale;           // Entrée digitale où le bouton est connecté
  bool boutonAppuye;            // Etat du bouton
  unsigned long date;           // Date à laquelle on a commencé à appuyer sur le bouton 
};

//----------------------------------------------------------------------------------------------------------------------------
// Définition des boutons
//----------------------------------------------------------------------------------------------------------------------------
Bouton off;   // Bouton OFF (relais des pédales de frein et d'embrayage + bouton Off de la commande au volant)
Bouton memo;  // Définition du bouton de mémorisation vitesse
Bouton plus;  // Définition du bouton +
Bouton moins; // Définition du bouton -

//----------------------------------------------------------------------------------------------------------------------------
// Définition des fonctions qu'on associe aux boutons
//----------------------------------------------------------------------------------------------------------------------------
enum FonctionBouton {
  RIEN,      // Fontion neutre, il n'y a rien à faire
  OFF,       // Fonction OFF
  MEMO,      // Fonction mémorisation vitesse
  MEMOLONG,  // Fonction associée à l'appui long sur le bouton mémorisation
  PLUS,      // Fonction +
  PLUSLONG,  // Fonction appui long sur +
  MOINS,     // Fonction -
  MOINSLONG, // Fonction appui long sur -
};

//----------------------------------------------------------------------------------------------------------------------------
// Type énuméré permettant de définir les états des boutons
//----------------------------------------------------------------------------------------------------------------------------
enum EtatBouton {
  RELACHE,                // Le bouton est relâché (circuit ouvert)
  APPUYE,                 // Le bouton est appuyé (circuit fermé)
  MAINTIEN_LONG,          // Le bouton est maintenu appuyé (circuit fermé)
};

//----------------------------------------------------------------------------------------------------------------------------
// Déclaration des variables globales utilisées dans le code
//----------------------------------------------------------------------------------------------------------------------------
bool erreur = true;                       // Variable d'erreur
bool erreurmemo = false;                  // Variable d'erreur pour le bouton MEMO et empêcher le reset automatique s'il est détecté bloqué à l'initialisation
int vitessemini = 1500;                   // Vitesse minimum pour l'activation du régulateur de vitesse
int vitessememoire = 0;                   // Vitesse mise en mémoire pour la régulation
String vitesseaffichage = String(0);      // Vitesse convertie en type String pour l'affichage
int pasvitesse = 50;                      // Pas avec lequel on incrémente ou diminue la valeur de vitesse
int gdpasvitesse = 250;                   // Pas avec lequel on incrémente ou diminue la valeur de vitesse lors d'appui long
int margevitesse = 5;                     // Marge de vitesse permettant de ne pas trop solliciter la régulation de vitesse
int positionservomini = 5;                // Position minimale du servomoteur
int positionservomax = 97;                // Position maximale du servomoteur
int positionservo1 = 200;                 // Position initiale du servomoteur utilisée pour la fonction de vérification
int chronoservo = 0;                      // Chronomètre pour évaluer les mouvements du servomoteur
bool regulation = false;                  // Régulateur actif ou non
bool etatantelectro = false;              // Etat antérieur de l'électroaimant (pour éviter le clignotement des dessins play et pause)
bool cmdeoff = true;                      // Flag de vérification de l'état OFF pour ne pas exécuter le cas "default" dans le loop quand OFF est ouvert
String commande = "commande";
String appuyee = "appuyee";
String espace = " ";
String txtvitesse = "Vitesse";
String insuffisante = "insuff";
String txtmemo = "Memo";
String txtoff = "Off";
String txtplus = "Plus";
String txtmoins = "Moins";
FonctionBouton precfonc = RIEN;           // Fonction bouton à n-1

//#####################################################################
//## Déclaration des fonctions                                       ##
//#####################################################################

//----------------------------------------------------------------------------------------------------------------------------
// Fonction "etatDuBouton" qui gère les états des boutons (revoie un des états contenus dans la variable énumérée EtatBouton)
//----------------------------------------------------------------------------------------------------------------------------
EtatBouton etatDuBouton (Bouton *boutonATraiter) {
  EtatBouton etat = RELACHE;                                                   // Valeur qui sera renvoyée comme résultat de cette fonction, par défaut RELACHE
  bool etatSignal = !digitalRead(boutonATraiter->entreeDigitale);              // Lire l'état de l'entrée dans une nouvelle variable temporaire

  if ( etatSignal ) {                                                          // Si le bouton semble avoir été appuyé (pas de signal, ou signal = 0/false)
    if (!boutonATraiter->boutonAppuye) {                                       // Si c'est la première fois que le bouton est détecté appuyé, on lance un chrono
      boutonATraiter->date = millis();
    }
    boutonATraiter->boutonAppuye = true;                                       // On attribue au bouton l'état appuyé
    if (millis () - boutonATraiter->date > TEMPS_MAINTIENLONG) {               // Si le bouton est appuyé depuis plus du temps défini
      etat = MAINTIEN_LONG;                                                    // Renvoyer l'état appui long
    }
    else {                                                                     // Sinon on est sur un simple appui
      etat = APPUYE;                                                           // Renvoyer l'état appuyé
    }
  }
  else {                                                                       // Si le bouton n'est pas appuyé
    boutonATraiter->boutonAppuye = false;                                      // On attribue au bouton l'état non appuyé
    etat = RELACHE;                                                            // Renvoyer l'état relaché
  }
  return etat;                                                                 // Renvoyer l'état du bouton en sortie de fonction
}

//----------------------------------------------------------------------------------------------------------------------------
// Fonction "lectureCommande" qui contrôle les instructions données par le bouton multiposition
//----------------------------------------------------------------------------------------------------------------------------
FonctionBouton lectureCommande () {
  FonctionBouton fonction = RIEN; // Fonction renvoyée (par défaut: RIEN)
  // Lecture des états des boutons
  EtatBouton etatoff   = etatDuBouton( &off );
  EtatBouton etatmemo  = etatDuBouton( &memo );
  EtatBouton etatplus  = etatDuBouton( &plus );
  EtatBouton etatmoins = etatDuBouton( &moins );
    
  // Définition des fonctions en fonction de l'état des boutons
  // Etat OFF
  if ( etatoff == RELACHE ) {
    fonction = OFF;
  }

  // Etat MEMO
  if ( etatmemo == APPUYE ) {
    fonction = MEMO;
  } else if ( etatmemo == MAINTIEN_LONG ) {
    fonction = MEMOLONG;
  }

  // Etat PLUS
  if ( etatplus == APPUYE ) {
    fonction = PLUS;
  } else if ( etatplus == MAINTIEN_LONG ) {
    fonction = PLUS; //PLUSLONG
  }

  // Etat MOINS
  if ( etatmoins == APPUYE ) {
    fonction = MOINS;
  } else if ( etatmoins == MAINTIEN_LONG ) {
    fonction = MOINS; //MOINSLONG
  }

  // Renvoi de la fonction associée
   return fonction;
}

//#####################################################################
//## Initialisation du circuit (fonction setup)                      ##
//#####################################################################

void setup() {
  Serial.begin(9600);                    // Ouvre le port série
  
  // 1) Déclaration des pins:
    // a) pour les boutons
  pinMode(BTNOFF, INPUT);     // On déclare le pin "BTNOFF" comme un pin d'entrée 
  pinMode(BTNMEMO, INPUT);    // On déclare le pin "BTNMEMO" comme un pin d'entrée
  pinMode(BTNPLUS, INPUT);    // On déclare le pin "BTNPLUS" comme un pin d'entrée
  pinMode(BTNMOINS, INPUT);   // On déclare le pin "BTNMOINS" comme un pin d'entrée
  off.entreeDigitale   = BTNOFF;
  memo.entreeDigitale  = BTNMEMO;
  plus.entreeDigitale  = BTNPLUS;
  moins.entreeDigitale = BTNMOINS;
    // b) pour les relais
  pinMode(CMDELECTROAIMANT, OUTPUT);
  pinMode(CMDACCELERATION, OUTPUT);
  pinMode(CMDDECELERATION, OUTPUT);
    // c) pour l'asservissement du servomoteur et le capteur de vitesse: pas besoin, ce sont des entrées analogiques
  Serial.println(F("Pins initialisés"));

  // 2) Initialisation erreur
  erreur = false;

  // 3) Initialisation commandes
  digitalWrite(CMDELECTROAIMANT, HIGH);
  digitalWrite(CMDACCELERATION, HIGH);
  digitalWrite(CMDDECELERATION, HIGH);
 
  // 4) Commandes:
    // a) Vérification de la commande MEMO
  if (!digitalRead (memo.entreeDigitale)){
    erreurmemo = true; // Le bouton MEMO détecté "bloqué" au démarrage doit pouvoir empêcher la réinitialisation dans le loop
    Serial.println(F("Lecture initialisation: MEMO"));
    delay (5000); // On prend 5 secondes pour lire le message (et tant pis si on stoppe le code, on n'est qu'au stade de l'initialisation, ce n'est pas grave)
    // Ne pas laisser le régulateur fonctionner si ce bouton est appuyé au départ
    erreur = true;
  }
    // b) Vérification de la commande MOINS
  if (!digitalRead (moins.entreeDigitale)){
    Serial.println(F("Lecture initialisation: MOINS"));
    delay (5000); // On prend 5 secondes pour lire le message (et tant pis si on stoppe le code, on n'est qu'au stade de l'initialisation, ce n'est pas grave)
    // Ne pas laisser le régulateur fonctionner si ce bouton est appuyé au départ
    erreur = true;
  }
    // c) Vérification de la commande PLUS
  if (!digitalRead (plus.entreeDigitale)){
    Serial.println(F("Lecture initialisation: PLUS"));
    delay (5000); // On prend 5 secondes pour lire le message (et tant pis si on stoppe le code, on n'est qu'au stade de l'initialisation, ce n'est pas grave)
    // Ne pas laisser le régulateur fonctionner si ce bouton est appuyé au départ
    erreur = true;
  }
    // d) Vérification de la commande OFF (on ne bloque pas celle là, car on peut rester appuyé sur le frein ou l'embrayage, par contre on met juste un message à l'écran)
  if (digitalRead (off.entreeDigitale)){
    Serial.println(F("Lecture initialisation: OFF"));
    delay (1000); // On prend 1 seconde pour lire le message (et tant pis si on stoppe le code, on n'est qu'au stade de l'initialisation, ce n'est pas grave)
  }
  // 5) Si on n'a pas eu d'erreur (dans les if précédents) et qu'on n'a pas appuyé sur OFF, on affiche qu'aucune commande n'a été appuyée
  else if (!erreur) {
    Serial.println(F("Lecture initialisation: RIEN"));
    delay (1000); // On prend 1 seconde pour lire le message (et tant pis si on stoppe le code, on n'est qu'au stade de l'initialisation, ce n'est pas grave)
  }
    
  // 6) Si pas d'erreur à l'initialisation, on informe que tout est prêt
  if (!erreur) {
    Serial.println(F("Fin initialisation"));
  }
}


//#####################################################################
//## Fonction loop                                                   ##
//#####################################################################

void loop() {
  if (!erreur){                          // Si pas d'erreur détectée soit dans le setup soit dans le loop
      switch (lectureCommande ()){       // On lit la commande qui retournera quelque chose différent de RIEN si un bouton a été appuyé
        
        case OFF : {
          if (precfonc != OFF) {   // Pour éviter d'afficher le message à chaque passage dans le loop (Attention, ici, on n'aura pas le réaffichage du ON, car trop furtif, precfonc repasse trop vite à RIEN)
            Serial.println(F("Loop: OFF"));
          }
          digitalWrite(CMDACCELERATION, HIGH);
          digitalWrite(CMDDECELERATION, HIGH);
          digitalWrite(CMDELECTROAIMANT, HIGH);
          cmdeoff = true;
          delay (1000); // 1 seconde, histoire d'être sur que l'electroaimant soit bien désactivé
          precfonc = OFF;
        }
        break;
        
        case MEMO : {
          if (precfonc != MEMO) {  // Pour éviter d'afficher le message à chaque passage dans le loop
            Serial.println(F("Loop: MEMO"));
          }  
          cmdeoff = false;
          precfonc = MEMO;
          // Rien
        }
        break;
        
        case MEMOLONG : {
          if (precfonc != MEMOLONG) {  // Pour éviter d'afficher le message à chaque passage dans le loop
            Serial.println(F("Loop: MEMOLONG"));
          }
          cmdeoff = false;
          precfonc = MEMOLONG;
          // Rien
        }
        break;
        
        case PLUS : {
          if (precfonc != PLUS) {  // Pour éviter d'afficher le message à chaque passage dans le loop
            Serial.println(F("Loop: PLUS"));
          }
          digitalWrite(CMDACCELERATION, LOW);
          digitalWrite(CMDDECELERATION, HIGH);
          digitalWrite(CMDELECTROAIMANT, LOW);
          cmdeoff = false;
          precfonc = PLUS;
        }
        break;
        
        case MOINS : {
          if (precfonc != MOINS) { // Pour éviter d'afficher le message à chaque passage dans le loop
            Serial.println(F("Loop: MOINS"));
          }
          digitalWrite(CMDACCELERATION, HIGH);
          digitalWrite(CMDDECELERATION, LOW);
          digitalWrite(CMDELECTROAIMANT, LOW);
          cmdeoff = false;
          precfonc = MOINS;
        }
        break;
        
        default : {
          if (!cmdeoff) {
            if (precfonc != RIEN) {  // Pour éviter d'afficher le message à chaque passage dans le loop
              Serial.println(F("Loop: ON"));
            } 
            digitalWrite(CMDACCELERATION, HIGH);
            digitalWrite(CMDDECELERATION, HIGH);
            digitalWrite(CMDELECTROAIMANT, LOW);
          }
          cmdeoff = false;
          precfonc = RIEN;
        }
        break;
      }
      
    
  }
  else { // En cas d'erreur relevée, on stoppe le régulateur
    Serial.println(F("Arrêt d'Urgence dans le loop"));
    // Si on appuie longtemps sur MEMO, on peut réinitialiser le régulateur
    if (!erreurmemo){    // Si le bouton n'était pas bloqué à l'initalisation, on autorise la réinitialisation
      if (lectureCommande () == MEMOLONG) {
        delay (5000);
        asm volatile("jmp 0x00");  // Réinitialisation depuis le début
      }
    }
  }
}

 

  • Well done! 2
Link to comment
Share on other sites

Tests de la matinée: Avec la résistance à la masse, le moteur ne bouge pas, mais tout fonctionne bien. J'ai donc viré cette résistance, et devinez quoi: j'ai toujours mes resets intempestifs :angry:

 

En gros c'est l'Arduino qui se remet à zéro quand le relais d'accélération (ou de décélération) s'arrête, c'est à dire au moment même où je n'ai plus besoin d'appuyer ou de relâcher l'accélérateur via le moteur du régulateur (donc quand on arrête de l'alimenter). La seule explication que je vois, c'est un pic de tension parasite qui arrive à passer par les relais (ou par l'alimentation 12-5V?) et qui perturbe l'Arduino. Je dois contrôler ça avec l'oscilloscope je pense.

 

Ou alors, je reprends le principe de la résistance, mais que je mets en parallèle du moteur. Elle ne servira plus à réduire sa vitesse comme je le voulais, mais à "absorber" ce pic de tension supposé. Quoi qu'il en soit, c'est bien chiant :angry:

Link to comment
Share on other sites

oui, normalement on met une diode anti-retour dans les montages des relais à bobine. Faut penser aussi que la bobine du relais consomme un peu de jus, il est souvent conseillé de piloter le relais avec une source d'alimentation extérieure à celle de l'Arduino, pilotée par un transistor.

 

montage_relais.jpg

 

VCC = 9V si mes souvenirs sont bons dans ce montage, fournis par une alim 220->9V. Le 9V est supporté par l'arduino (qui supporte jusqu'à 12-14V) mais qui va réguler toutes ses sorties sur 5V.

RL1 : relais à bobine 9V.
Q1 est activé par l'arduino via R4 (sortie digitale de l'arduino). Le jus est fourni directement par l'alim 9V et ne transite pas via l'arduino, ce qui permet de ne pas utiliser autre chose que le signal de la sortie.


Il faut toujours garder en tête de n'utiliser les signaux de l'arduino que comme tels, et pas comme alimentations. Un autre exemple : j'avais fait un montage pour carnaval de "robots" qui jouaient de la musique. J'animais environ 5 robots via des servomoteurs, l'alim des servomoteurs était extérieure, l'arduino ne servait qu'à donner les commandes des positions.

 

Enfin, si t'as peur qu'il y ait des trucs chelous avec l'équippement piloté, tu peux aussi utiliser des opto-coupleurs à la place du transistor Q1, ca permet d'isoler vraiment tes circuits sans risquer de cramer ton arduino...

 

Edit : dans ton code t'as beaucoup de "delay()", qui sont des fonctions bloquantes. C'est fortement déconseillé dans un système embarqué.

 

  • Good idea! 2
Link to comment
Share on other sites

Les relais que j'utilise sont vendus comme compatibles avec Arduino, et ils comportent déjà un circuit de commande par transistor. Sur la plaquette de 4 relais que j'utilisais précédemment, j'avais même des optocoupleurs, mais même avec ça mon montage sautait. Je vais quand même mettre une diode avant la broche IN, car le "circuit relais" n'en possède pas (la Zener ne sert que pour allumer la diode verte), et ça pourrait bien en effet remonter par là. Voilà une photo de ce que c'est côté "commande" (et qui n'est pas représenté sur mon schéma électrique):

IMG_0080.JPG.f2860ce5f14563a92a6e1e25728611a8.JPG

 

Concernant l'alimentation, je pique en effet les 5V de l'Arduino pour une raison toute simple: ça facilite le diagnostic. Dans mon montage précédent, je prenais l'alimentation derrière mon convertisseur 12V-5V, mais le diag était complexe: il me fallait à la fois garder l'alimentation de mon convertisseur mais sans alimenter l'Arduino qui lui était alimenté par l'USB... Un coup à cramer l'USB de mon ordi si je foire le cablage ou qu'un court circuit se produit. Là au moins c'est l'Arduino qui gère tout. En terme de consommation, je trouve que c'est très raisonnable, avec deux relais activés (ce qui sera le maximum), j'ai 150 mA qui sont tirés de l'USB (j'avais presque 950 mA quand j'avais ma grosse fuite de courant), et donc en temps normal, on est à 80 mA.


Concernant les delay(), je sais que c'est un truc que tu n'aimes pas, mais ils sont positionnés à des endroits stratégiques et dans un but précis: stopper le code pour qu'aucune action ne puisse être faite. Par exemple: relacher la tension du cable d'accélérateur suffisamment longtemps si l'électroaimant "colle", ou que sais-je, ou alors bien faire en sorte qu'on puisse lire des messages d'erreur qui seront affichés à terme sur l'écran, également dans le but de ne rien faire d'autre en attendant: dans la phase d'initialisation (setup) pour moi ce n'est pas grave, et je ne compte pas multiplier leur utilisation dans les évolutions du code (sauf pour des fonctions de secours où je voudrais volontairement bloquer le code).

Link to comment
Share on other sites

ok pour le circuit de relais, il y a visiblement de quoi faire ça relativement proprement, je ne pense pas qu'ajouter une diode améliore beaucoup ton problème, je vois un truc à trois pattes sur le circuit, c'est peut-être un transistor, du coup la diode ou pas, c'est entre le transistor et le relais qu'elle serait nécessaire... Par contre, le VCC de ton montage relais il faut justement le brancher en amont de l'arduino, c'est le but de la manip...

Pour les "delay()", ce n'est pas que "je n'aime pas ça" comme un caprice de développeur, c'est que ce n'est vraiment pas un truc à faire... mais après tout, tu fais comme tu veux... ;)

Enfin, du coup pour ton problème de coupure il y a peut être l'arduino qui s'est déjà pris un coup et qui est à moitié grillé, ou des branchements mal faits (court circuits involontaires lors de la soudure, ca arrive souvent, surtout sur les plaques d'essai). Ca peut aussi venir de l'alim qui ne fournit peut-être pas assez de jus...

 

Link to comment
Share on other sites

il y a une heure, Zorro_X a dit :

 

Pour les "delay()", ce n'est pas que "je n'aime pas ça" comme un caprice de développeur, c'est que ce n'est vraiment pas un truc à faire...

Quand je dis ça, ce n'est pas contre toi spécifiquement, car tu as plutôt une philosophie du "code propre" que je m'efforce à suivre, mais quand tu regardes les tutos Arduino sur Internet, il n'y en a pas un seul qui n'utilise pas le delay(), c'est assez dingue je trouve :nosweat: Cependant je les utilise vraiment en connaissance de cause car je veux vraiment stopper toute instruction pendant un temps donné, et c'est cette instruction qui s'y prête le mieux :) 

 

 

il y a une heure, Zorro_X a dit :

Enfin, du coup pour ton problème de coupure il y a peut être l'arduino qui s'est déjà pris un coup et qui est à moitié grillé, ou des branchements mal faits (court circuits involontaires lors de la soudure, ca arrive souvent, surtout sur les plaques d'essai). Ca peut aussi venir de l'alim qui ne fournit peut-être pas assez de jus...

 

Quand le module moteur/électroaimant est débranché je n'ai aucun problème, aussi bien quand c'est alimenté par la batterie de la voiture, que sur une alimentation stabilisée ou alimenté en USB. Peut être que l'Arduino a pris un coup mais il n'en donne aucun signe évident en tout cas :hein: J'ai pas osé tenter avec un autre Arduino, mais je crains que ce ne soit pareil. Concernant les soudures, je les ai quasi toutes reprises et elles sont isolées par du flux de soudure en résine, j'estime à 1% le taux de chance pour qu'il y ait un court circuit :laugh:

 

Je vais déjà faire un test avec une résistance en parallèle du moteur comme je disais. Je vais faire étape par étape :) 

Link to comment
Share on other sites

il y a une heure, totojest a dit :

Quand le module moteur/électroaimant est débranché je n'ai aucun problème

 

Vu que le moteur et l'électroaimant sont isolés par les relais, il ne reste que le rhéostat, commence par là si tu veux vérifier du câblage... tu peux déjà essayer en ne branchant que le rhéostat (sans brancher le moteur/électroaimant) pour voir ce qu'il se passe...
 

Sinon question bête, est-ce-que ton arduino est assez loin de ton électroaimant ? pareil pour le rhéostat ? parce que l'arduino est extrêmement sensible aux signaux parasites ; tes résistances 10K doivent être là un peu pour ça je suppose aussi, mais une bobine plus de l'électroaimant, c'est peut-être un peu trop pour un simple tirage vers le bas... 😕 
après ce n'est qu'une idée...

 

 

il y a une heure, totojest a dit :

il n'y en a pas un seul qui n'utilise pas le delay(), c'est assez dingue je trouve

ouaip, je trouve ça dingue aussi... bizarre... après un code qui utilise du delay() est plus facile à comprendre qu'un automate ré-entrant en fonction d'un état global... m'enfin bon, comme dit : c'est toi qui vois !

Link to comment
Share on other sites

Il y a 16 heures, Zorro_X a dit :

Vu que le moteur et l'électroaimant sont isolés par les relais, il ne reste que le rhéostat, commence par là si tu veux vérifier du câblage... tu peux déjà essayer en ne branchant que le rhéostat (sans brancher le moteur/électroaimant) pour voir ce qu'il se passe...

Quand tu parles du rhéostat, tu parles du potentiomètre qui est dans le module moteur/electroaimant? Si c'est le cas, oui, j'ai testé en le débranchant, et j'ai toujours le soucis. 

 

Il y a 16 heures, Zorro_X a dit :

Sinon question bête, est-ce-que ton arduino est assez loin de ton électroaimant ? pareil pour le rhéostat ? parce que l'arduino est extrêmement sensible aux signaux parasites ; tes résistances 10K doivent être là un peu pour ça je suppose aussi, mais une bobine plus de l'électroaimant, c'est peut-être un peu trop pour un simple tirage vers le bas... 😕 
après ce n'est qu'une idée...

Très bonne remarque, mais le module moteur/électroaimant est dans la baie moteur, l'Arduino est dans l'habitacle, et accessoirement, éloigné aussi de toute source d'interférence en principe. 

Link to comment
Share on other sites

Tu as fait des tests hors de la voiture, je veux dire en simulation?

Si oui tu avais le même genre de soucis?

Link to comment
Share on other sites

ok... est-ce-qu'en débranchant un truc ca ne plante plus ? si oui lequel ?

Sinon, ca peut venir du code aussi, je n'ai pas tout analysé dans le détail, mais j'ai l'impression que t'exécutes chaque commande en boucle tant qu'il n'y en a pas une nouvelle qui arrive... 😕 C'est peut-être normal, mais je ne vois pas forcément l'intérêt...

Link to comment
Share on other sites

Il y a 3 heures, Ermi a dit :

Tu as fait des tests hors de la voiture, je veux dire en simulation?

Si oui tu avais le même genre de soucis?

J'ai testé en dehors de la voiture et ça marche comme je veux. J'ai testé dans la voiture, moteur et électroaimant débranchés (ils sont sur la même prise), et ça marche nickel. C'est vraiment dès que je les branche que j'ai le soucis.
 

 

Il y a 2 heures, Zorro_X a dit :

Sinon, ca peut venir du code aussi, je n'ai pas tout analysé dans le détail, mais j'ai l'impression que t'exécutes chaque commande en boucle tant qu'il n'y en a pas une nouvelle qui arrive... 😕 C'est peut-être normal, mais je ne vois pas forcément l'intérêt...

En effet, la logique de mon code est simplement de tourner en boucle pour observer s'il y a des variations de changement d'état de ma commande d'entrée (les interrupteurs). A terme il faudra que cette boucle prenne en compte le paramètre "vitesse" pour ajuster l'accélération.

 

S'il y a un moyen de faire autrement, je suis preneur :) 

Link to comment
Share on other sites

Il est branché comment ton arduino à la voiture ? ou tu le fais sur l'ordi portable pour tester sur la voiture ?

Si tu le fais sur l'ordi, il peut y avoir une trop grosse différence de potentiel si t'as pas les masses communes avec la voiture. Tu peux tenter de lier la masse de l'arduino à la masse de la voiture.
Si c'est branché sur la voiture, il faudrait voir comment c'est branché, il faut bien faire attention aux masses quand même.


Pour le code, t'es sur la bonne voie avec ton switch/case. Mais dans un appareil à boutons tu dois savoir détecter surtout les changements d'état des boutons ( notamment l'appui, pour pouvoir agir en conséquence) et éventuellement gérer un état interne de ton programme si plusieurs modes de fonctionnement sont envisageables par exemple. Mais là j'ai l'impression que tu mélanges les deux.
Sinon, ton "delay(5000);" à la fin, il est sensé servir à quoi ? Parce que là il ne fait que te faire patienter 5 secondes avant le redémarrage (?!)

Link to comment
Share on other sites

il y a 1 minute, Zorro_X a dit :

Il est branché comment ton arduino à la voiture ? ou tu le fais sur l'ordi portable pour tester sur la voiture ?

J'ai une alim réglable de ce type, avec comme entrée un 12V après contact (pris sur le contacteur de frein), et une masse récupérée sur la colonne de direction. J'ai réglé la sortie à 5V au multimètre.

IMG_2376.thumb.jpg.6ed1507297ae3efcfaf4f18160affffc.jpg

 

IMG_2377.thumb.jpg.38e2b7330bbb58a2d2cf32c001153e3d.jpg

 

il y a 1 minute, Zorro_X a dit :

Si tu le fais sur l'ordi, il peut y avoir une trop grosse différence de potentiel si t'as pas les masses communes avec la voiture. Tu peux tenter de lier la masse de l'arduino à la masse de la voiture.

Quand je passais par une alimentation USB (depuis l'ordi ou depuis un chargeur allume cigare), j'avais beaucoup moins de problème, sans doute parce que j'avais plus de "filtrage", mais ça le faisait de temps en temps quand même.

 

il y a 3 minutes, Zorro_X a dit :

Pour le code, t'es sur la bonne voie avec ton switch/case. Mais dans un appareil à boutons tu dois savoir détecter surtout les changements d'état des boutons ( notamment l'appui, pour pouvoir agir en conséquence) et éventuellement gérer un état interne de ton programme si plusieurs modes de fonctionnement sont envisageables par exemple. Mais là j'ai l'impression que tu mélanges les deux.

Dans l'idée, on reste toujours sur un fonctionnement où la boucle sert à surveiller si un état change ou pas donc. Mais je serais intéressé pour que tu me dises un peu plus en détail ce que je mélange? Je suis encore un noob en codage Arduino, ce truc là ça fait bien un an et demi que j'ai commencé et que c'est toujours aux balbutiements (quant à mes commandes d'autoradio, je dois aussi les mettre à jour, car il y a des trucs qui ne marchent clairement pas comme il faut :laugh: On est sur du provisoire qui dure!)

 

il y a 10 minutes, Zorro_X a dit :

Sinon, ton "delay(5000);" à la fin, il est sensé servir à quoi ? Parce que là il ne fait que te faire patienter 5 secondes avant le redémarrage (?!)

Là encore le but est clairement de figer le code avant que l'Arduino ne reboote, ça sert uniquement à "prendre du temps" pour que toutes les actions "hardware" aient le temps de se terminer. On est dans une exception: si le code a levé une erreur (que, actuellement, il n'est possible d'avoir qu'à l'initialisation, mais qui plus tard pourra être levée si un état indésirable est détecté dans la boucle), et que le bouton MEMO n'est pas bloqué fermé (détecté par le booleen erreurmemo), alors un maintien long du bouton MEMO doit permettre de rebooter l'Arduino (par exemple pendant que je roule, pour m'éviter d'avoir à trifouiller sous le volant trop longtemps, question de sécurité :)).

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...

Important Information

By using this site, you agree to our terms Terms of Use of use and privacy policy Privacy Policy.