Besoin d aide pour projet de boite de vitesses séquentielle de tracteur tondeuse de course :D

Salut a tous...
Je me présente, encore vite fait, pour poser le décors

Christophe... 39ans... bidouilleur fou qui touche à tout et electricien de métier...

Une de mes passions... entres les helicos RC , l'impression 3D, et les énergies alternatives...
Est faire la course avec un engin de mort n etaint absolument pas conçus pour ca .... : un tracteur tondeuse ! :smiley:

Je fait partis de l asso démarrage Imminent...

... nous Somme quelque tarés à faire mumuse avec des tracteurs tondeuses...

Et donc... dans mes délires bidouillatoires... je me suis mis en tête de modifier ma commande de vitesses... et de virer le levier mécanique mal placé, pour avoir une commande séquentielle avec palettes au volant :wink:

La commande de BV d un tracteur tondeuse est un simple levier allant de la marche arrière à la 5 ou 6ieme vitesse qu un gros servomoteur est capable de manipuler...

Et donc pour le matos...
Je prévois un gros motoreducteur 12v commander par un pont en H qui lui-même seras commandé par l'electronique d'un servo de modélisme dont la mécanique est HS.... ce qui me donne un gros servo standard....

Que je doit donc contrôler via une carte arduino uno et 2 boutons poussoirs... et éventuellement après... une fois que tout fonctionne... ajouter un afficheur 7 segments pour afficher au tableau de bords la vitesse sélectionnée...

Donc voilà les grande lignes... je détaillerai dans le message suivant mes besoin et problème que je rencontre au niveau de la programmation...

OK, donc un appui sur un des boutons change l'angle du "gros servo"

Pour simplifier votre gestion des boutons, éventuellement utilisez la librairie de @bricoleau

Bonjour akoirium

Voilà du fun!

Dire que la première Formule 1 à avoir ce système a été une Ferrari! Est-ce-que ton tracteur-tondeuse est rouge!
Restons sérieux, le servo envoie une impulsion en avant ou en arrière suivant que l'on monte ou descend les vitesses, ou le servo "avance" toujours plus loin suivant la vitesse à engager?

Cordialement
jpbbricole

oui ... on se mare bien

le tracteur etait rouge a l'origine....
mais maintenant il est noir ... j'aime pas les ferrari :smiley:

pour info ... cet engin de mort avec moteur bicylindres de 20cv (691cm3) est capable d'atteindre sans probléme le 80 a 100 km/h :smiley:

bon treve de pleasantries... voici ou j'en suis avec la prog...

J'ai commencer mes tests avec un servo clasique et ce code trouvé sur le net :

/* Inclut la librairie Servo pour manipuler le servomoteur */
#include <Servo.h>

int bp1 = 2;
int bp2 = 3;

int position = 0;

/* Créer un objet Servo pour contrôler le servomoteur */
Servo monServomoteur;

void setup()
{
  // Bouton poussoir 1
  pinMode(bp1, INPUT_PULLUP);
  pinMode(bp2, INPUT_PULLUP);

  // Attache le servomoteur à la broche 2
  monServomoteur.attach(5);
  monServomoteur.write(0);

  Serial.begin(9600);
}

void loop()
{
  // Récuperer valeur de bp1
  int b1 = digitalRead(bp1);
  int b2 = digitalRead(bp2);

  // Si Appuie BP1
  if (b1 == LOW) {
    monServomoteur.write(position);
    position = position + 1;
    if (position > 180) {
      position = 180;
    }
    delay(10);
  }

  // Si Appuie BP2
  if (b2 == LOW) {
    monServomoteur.write(position);
    position = position - 1;
    if (position < 0) {
      position = 0;
    }
    delay(10);
  }

  Serial.print("Position du servo : "); Serial.println(position);

}

je l'ai juste legerement modifié pour avoir une incrémentation par paliers de 30° et augmenté le delay a 300ms pour ne pas avoir de saut de vitesse si l'appuie sur le bp est trop long...
ca fonctionne mais ... forcement il y a un mais ... si non ca serais trop facile ...
Le servo ne fait pas tout a fait ce que je veut sans que j'en comprenne la cause...

donc a l'allumage le servo s'initialise et fait un allé retour de 0 a 180° ( d'ailleurs ca m'embete un peu... j'aimerais qu'il ne bouge pas a la mise sous tension...)

puis si j'appuie une fois sur le bouton 1 .... il ne se passe rien... si j'appuie une seconde fois... la il bouge de 30° ... et ainsi de suite jusqu’à 180°.
Mais arrivé a 180... si j'appuie sur le bouton 2 ... il ne se passe rien et je doit appuier une seconde fois pour que le servo descende de 30°...

Mais c'est pas fini ....

si le servo est dans une position intermédiaire... par exemple j'appuie pour passer de la première a la seconde... si j’appuie sur le bouton pour rétrograder en première ... ce con passe en troisième !!!! RRRHHAAAAAA !!!! la c'est vraiment chiant !!!
et si j’appuie une seconde fois pour rétrograder... la ca fonctionne et il reviens en seconde... ( le pb est le même dans les 2 sens ...)

bref je ne sais pas ce qui cloche avec cette prog...

Mais bon ... d'un autre coté ce n'est pas tout a fait le mode de fonctionnement que je recherche... mais si qq peut me dire ce qui vas pas ... je me coucherais moins bette et ca me permettrait de tester la mécanique même si le programme final n'est pas prêt ...

voici ce que je cherche exactement a faire dans la prog :

En course ... il arrive souvent que l'on casse une boite .... et en urgence ... on remplace avec ce qu'on as sous la main ... et donc ... si on pète sa boite 6 vitesse... on monte a l'arrache en 30min la boite 5 vitesses qu'on a mis de coté au cas ou pour le week-end de courses :smiley:
et donc ... la mécanique de commande n'est plus la même ...

sachant cela ... j'aimerai déclarer dans le code une variable par vitesses avec une position de servo définie pour chaque vitesses...
et incrémenter ou decrementer ces variables avec les palettes au volant...

ce qui me permet dans le pire des cas... d'avoir facilement accès au programme avec un pc portable sur le circuit et modifier les valeurs angulaires pour chaque vitesses en fonction de la nouvelle boite ...

J'aimerai même aller plus loin ... et ajouter 2 BP pour régler la valeur de la variable de la vitesse sélectionnée et donc me passer de PC en cas de changement de boite ...

Et avec tout ca... je fouille et me renseigne....car oui j'ai oublier de le préciser .... je suis un newbie total et une grosse buse en programmation et Arduino !!!
mais bon si on m'explique longtemps .... :smiley: .... ... j'aimerais ajouter un afficheur 7 segments avec R, N, 1, 2, 3, 4, 5, 6....

Mais bon ... si j'arrive a passer les vitesses et que j'ai un système fiable cappable de tenir 20min de course sur une piste pleine d’ornières et de nids de pou... d'autruches ... plutots .... je serais dejas ravis !!!...

donc je remercie d'avance tous ceux qui m'apporteront leurs lumières !!!

Plutôt qu'allonger le delay(), il vaut mieux tester que le bouton a été relâché.
Tu pourrais aussi utiliser une machine à état pour gérer proprement la logique de fonctionnement de ton application.

bonsoir
fabriquer un servo en (ré)utilisant l’électroniquement d'un servo , j'ai déjà fait avec un LMD18200
et qq phototransistor
comment a tu positionné le capteur de recopie ?

de toutes façons c'est un système qui doit etre calibré unitairement, conseil en passant :smiley: n'utilise pas servo.write() valeur en degrés, mais servo.writeMicroseconds(us) , c'est beaucoup plus simple pour determiner les plages actives

Ton servo est fonctionnel actuellement ?

Merci de vos réponses...
Je vais potasser tout ça :wink:

Mon servo n est pas encore fonctionnel... il me faut réaliser le palonier de commande de vitesse... qui seras également raccordé mécaniquement au servo 9g dont j'aurais viré les engrenages pour récupérer l info de position...
Je doit aussi modeliser et imprimer en 3d une pièce qui supportera le servo sur le motoreducteur ...
Mais je n ais pas de doute sur le fonctionnement...
C est surtout la prog qui me pose problème...

Perso je pense que tu devrais inverser la proposition :grinning:

Bhen il n y a pas de raison...
J avais déjà fait cette bidouille avec un moteur d essuie glace...
ce coup ci c est pareil sauf que je n ai pas besoin d un servo aussi gros et j utilise un motoreducteur un poil plus petit :wink:

Bon si non ... je vois à peu près comment déclarer mes variables pour mes 6 vitesses, neutre, et marche ar...

Mais je sèche un peu pour activer mes variables avec mes 2 bp ....

La première chose à faire est d'éliminer les rebonds :

  • hard : condensateur de 100nF en // sur chaque bouton
  • soft : librairie bounce2

La librairie a l'avantage de posséder des méthodes sympas :
bounce_button.ino

Comme déjà dit, pour simplifier votre gestion des boutons, éventuellement utilisez la librairie de @bricoleau

un truc du genre (tapé ici)

#include <Servo.h>
Servo levierVitesse;
const byte pinServo = 5;

#include <simpleBouton.h> // cf @bricoleau @ http://forum.arduino.cc/index.php?topic=375232.0
const byte pinPalettePlus  = 2;  //Cablage : pin 4 --- bouton --- GND
const byte pinPaletteMoins = 3;  //Cablage : pin 5 --- bouton --- GND

simpleBouton boutonPlus(pinPalettePlus);
simpleBouton boutonMoins(pinPaletteMoins);

const int boite[] = {1100, 1250, 1400, 1550, 1700, 1850}; // les valeurs d'angles en µs
const byte nombreDeVitesses = sizeof boite / sizeof boite[0];
byte vitesse  = 0;  // vitesse par défaut

inline void reglerVitesse() {
  levierVitesse.writeMicroseconds(boite[vitesse]);
  Serial.print(F("Vitesse ")); Serial.print(vitesse);
  Serial.print(F("\tangle ")); Serial.println(boite[vitesse]);
}

void plus() {
  if (vitesse < nombreDeVitesses - 1) {
    vitesse++;
    reglerVitesse();
  }
}

void moins() {
  if (vitesse > 0) {
    vitesse--;
    reglerVitesse();
  }
}

void gestionPalettes() {
  boutonPlus.actualiser();
  if (boutonPlus.vientDEtreEnfonce()) plus();
  else {
    boutonMoins.actualiser();
    if (boutonMoins.vientDEtreEnfonce()) moins();
  }
}

void setup() {
  Serial.begin(115200);
  reglerVitesse();
  levierVitesse.attach(pinServo);
}

void loop() {
  gestionPalettes();
}

bouton + en D2, bouton - en D3, Servo en D5.
J'ai mis des angles aléatoires dans le tableau des vitesses

Le moniteur série à 115200 bauds devrait afficher les changements de vitesses à la hausse ou baisse quand vous appuyez sur les boutons

il faudra peut-être rajouter une petite gestion du temps d'attente pour que la vitesse soit bien changée avant de traiter un nouvel appui sur une palette.

Merci beaucoup !!!

J en attendait pas tant !... mais ça ressemble bien à ce que je cherche à faire...
Il ne me reste plus qu'à prendre un peu de temps pour comprendre parfaitement ce code et l'adapter à mes besoins :wink:

Et oui... pour les bp... j ai lu déjà différentes solutions pour éviter les rebonds...
Je vais également me pencher la dessus...

Enfin, je commence a me rendre compte que ce projet ne sera peut-être pas finalisé pour le 11 et 12 septembre... la date de notre grosse course annuelle ( a tayrac dans le 47 pour ceux que ça intéresse :wink: ) ...

La librairie de Bricoleau aussi gère cet aspect.

Adapter le rebond à la qualité des boutons (par défaut 20ms, ce qui peut être insuffisant) :

simpleBouton boutonPlus(pinPalettePlus, 50);
simpleBouton boutonMoins(pinPaletteMoins, 50);

Merci ;)...

Bon y a plus qu a...
Vivement le week-end !!! :smiley:

bon et bien... ...
un TRÈS grand merci a toi J-M-L !!!

je viens de tester en rentrant du taf ton bout de code avec un servo standard sur ma platine d’essais ...
Et bien même sans avoir a faire de l’anti rebond ou du delay ... ca fonctionne merveilleusement bien !!! :wink:
bon a voir en conditions réelles avec les parasites induits par le moteur ... mais ca s’annonce très bien tout ca... :wink:

je vais donc pouvoir m'atteler au vif du sujet et monter tout le matos sur le tracteur avant d'aller plus loin en programmation ....

Salut ...

j'aurais encore besoin de vos lumières...pour 2 petits soucis...
J'ai donc un code qui fonctionne ...
j'ai mixé le merveilleux code que m'as écrit J-M-L ... avec un code de compteur d'afficheur 7 segment ....
l'afficheur câblé avec des résistances de 470 ohm fonctionne mais ne donne pas la luminosité que j'attendais ... et j'ai fait un essais sans résistances... la luminosité est strictement le même ...

Afficheur chinoi de mauvaise qualité ou quelque chose m’échappe ? ...

Autre souci ... qui n'en est pas vraiment un ...
Je cherche a ajouter 2 bp pour faire varier l'es valeurs d'angles du servo de la vitesse sélectionnée...
mais la je doit dire que je sèche un peu...

voici donc mon code fonctionnel :

#include <Servo.h>
Servo levierVitesse;
const byte pinServo = 5;

#include <simpleBouton.h> // cf @bricoleau @ http://forum.arduino.cc/index.php?topic=375232.0
const byte pinPalettePlus  = 2;  //Cablage : pin 4 --- bouton --- GND
const byte pinPaletteMoins = 3;  //Cablage : pin 5 --- bouton --- GND

simpleBouton boutonPlus(pinPalettePlus);
simpleBouton boutonMoins(pinPaletteMoins);

const int a=6;
const int b=7;
const int c=8;
const int d=9;
const int e=10;
const int f=11;
const int g=12;
//const int bouton_plus = 2;
//const int bouton_moins = 3;
int etat_bouton;
int nombre = 1;
int mem_btn_plus = HIGH; //etat du bouton plus
int mem_btn_moins = HIGH; // etat du bouton moins

const int boite[] = {700, 930, 1160, 1390, 1620, 1850, 2080}; // les valeurs d'angles en µs
const byte nombreDeVitesses = sizeof boite / sizeof boite[0];
byte vitesse  = 1;  // vitesse par défaut

inline void reglerVitesse() {
  levierVitesse.writeMicroseconds(boite[vitesse]);
  Serial.print(F("Vitesse ")); Serial.print(vitesse);
  Serial.print(F("\tangle ")); Serial.println(boite[vitesse]);
}

void plus() {
  if (vitesse < nombreDeVitesses - 1) {
    vitesse++;
    reglerVitesse();
  }
}

void moins() {
  if (vitesse > 0) {
    vitesse--;
    reglerVitesse();
  }
}

void gestionPalettes() {
  boutonPlus.actualiser();
  if (boutonPlus.vientDEtreEnfonce()) plus();
  else {
    boutonMoins.actualiser();
    if (boutonMoins.vientDEtreEnfonce()) moins();
  }
}

void setup() {
  Serial.begin(115200);
  reglerVitesse();
  levierVitesse.attach(pinServo);
  digitalWrite(a, OUTPUT);
  digitalWrite(b, OUTPUT);
  digitalWrite(c, OUTPUT);
  digitalWrite(d, OUTPUT);
  digitalWrite(e, OUTPUT);
  digitalWrite(f, OUTPUT);
  digitalWrite(g, OUTPUT);
//  digitalWrite(bouton_plus, INPUT);
//  digitalWrite(bouton_moins, INPUT);
}

void loop() {
  gestionPalettes();
  etat_bouton = digitalRead(pinPalettePlus);
if ((etat_bouton != mem_btn_plus) && (etat_bouton == LOW)){
 nombre++;
  }
 mem_btn_plus = etat_bouton;
etat_bouton = digitalRead(pinPaletteMoins);
if ((etat_bouton != mem_btn_moins)&& (etat_bouton == LOW)){
  nombre--;
  }  
mem_btn_moins = etat_bouton;
affichage(nombre);
if(nombre < 0){
nombre = 0;
}
if (nombre > 6)
nombre = 6;
}
void affichage (int recu){
if (recu == 0){
  digitalWrite(a,HIGH);
  digitalWrite(b,HIGH);
  digitalWrite(c,HIGH);
  digitalWrite(d,LOW);
  digitalWrite(e,HIGH);
  digitalWrite(f,HIGH);
  digitalWrite(g,HIGH);
}
 if (recu == 1) {
  digitalWrite(a,LOW);
  digitalWrite(b,LOW);
  digitalWrite(c,HIGH);
  digitalWrite(d,LOW);
  digitalWrite(e,HIGH);
  digitalWrite(f,LOW);
  digitalWrite(g,HIGH);
}
 if (recu == 2){
  digitalWrite(a,LOW);
  digitalWrite(b,HIGH);
  digitalWrite(c,HIGH);
  digitalWrite(d,LOW);
  digitalWrite(e,LOW);
  digitalWrite(f,LOW);
  digitalWrite(g,LOW);
}
 if (recu == 3){
  digitalWrite(a,HIGH);
  digitalWrite(b,HIGH);
  digitalWrite(c,LOW);
  digitalWrite(d,HIGH);
  digitalWrite(e,HIGH);
  digitalWrite(f,LOW);
  digitalWrite(g,HIGH); 
}
 if (recu == 4){
  digitalWrite(a,HIGH);
  digitalWrite(b,HIGH);
  digitalWrite(c,HIGH);
  digitalWrite(d,HIGH);
  digitalWrite(e,LOW);
  digitalWrite(f,LOW);
  digitalWrite(g,HIGH); 
}
 if (recu == 5){
  digitalWrite(a,LOW);
  digitalWrite(b,HIGH);
  digitalWrite(c,HIGH);
  digitalWrite(d,LOW);
  digitalWrite(e,LOW);
  digitalWrite(f,HIGH);
  digitalWrite(g,HIGH);
}
if (recu == 6){
  digitalWrite(a,HIGH);
  digitalWrite(b,LOW);
  digitalWrite(c,HIGH);
  digitalWrite(d,HIGH);
  digitalWrite(e,LOW);
  digitalWrite(f,HIGH);
  digitalWrite(g,HIGH); 
}
 if (recu == 7){
  digitalWrite(a,HIGH);
  digitalWrite(b,LOW);
  digitalWrite(c,HIGH);
  digitalWrite(d,HIGH);
  digitalWrite(e,HIGH);
  digitalWrite(f,HIGH);
  digitalWrite(g,HIGH);
}
}

si quelqu'un a une idée je suis preneur ...

Plutôt déconseillé pour la survie de l'ARDUINO : 20mA maxi.
Essayer de placer l'afficheur derrière un plexiglas rouge, car en plein jour il sera illisible.

Salut

Je ne crois pas qu un plexi rouge soit suffisant...
Ce qui est étrange c est que si j allimente une partie de mon afficheur directement avec du 5v et une résistance de 470 ohms... il s allume normalement

Mais avec l arduino la luminosité est vraiment très faible...

Il y a qq chose qui m échappe mais je ne vois pas quoi...

Si non je cherche toujours à ajouter mes boutons de reglage fin des angles... mais plus je lis les tutos sur le net... et plus ça devient flou pour moi...

Autant si l afficheur ne fonctionne pas , c est pas trop grave car c est pas vraiment utile en course... pratique au demmarage pour être sûr d etre au neutre...
Autant, ces boutons de réglage, eux serais très utiles pour éviter d avoir à sortir un pc au bord de la piste en cas de soucis...

Il faudrait ajouter un ULN2803 (8 bits) ou ULN2003 (7 bits), pour augmenter le courant, mais il ne faudra pas faire d'essai sans résistances (un ULN2003 est capable de délivrer 500mA).
D'autre part l'ULN2003 ne va pas délivrer 5V à l'afficheur mais plutôt 4V. Les résistances devront être abaissées (220Ω pour 20mA).

inline void reglerVitesse() {
  levierVitesse.writeMicroseconds(boite[vitesse]);
  Serial.print(F("Vitesse ")); Serial.print(vitesse);
  Serial.print(F("\tangle ")); Serial.println(boite[vitesse]);
}

Que dit le moniteur série (à régler sur 115200) ?

Pourquoi avoir ajouté du code pour gérer les boutons avec digitalRead() alors que cette gestion est déjà faite dans gestionPalettes() ?