Gestion electro mécanique d'un embrayage moto

Désolé jpbbricole mais je ne comprend pas. Mais c'ets sans doute mon manque de maitrise du langage.
D'une part je n'arrive pas à intégrer la fonction pulsein à mon code et d'autre part je ne vois pas ou récupérer cette longueur d'impulsion.... pour l'intégrer au map.
En bref je patauge.
Pourtant c'est tellement simple avec un potentiometre avec par exemple:

(val = analogRead(rpmPin));            
       val = map(val, 0, 1023, 0, 40);

Je comprends bien, comme vous aviez écrit

Cela me semblait logique que RPM/60 soit égale à la fréquence du signal carré que vous avez mesuré, et vous me dites que ce n'est pas le cas.

Je ne connais rien en mécanique Auto/Moto, voyez vous une explication à ce rapport de 2 entre 800 et 1600?

La mesure analogique et pulsein n'ont rien à voir, je n'ai pas le temps, ce soir, pour te faire un exemple, mais fais une recherche uno pulsein tuto, tu trouvera des exemples.

Cordialement
jpbbricole

Bonjour louisduro

Voilà un exemple, j'ai mis un maximum de commentaires, ne te gêne pas de poser des questions :wink:

Le programme:

// https://www.arduino.cc/reference/en/language/functions/advanced-io/pulsein/

const int rpmPin = 5;     // Pin du signal RPM
unsigned long rpmPulse = 0;     // Mesure d'impulsion

const unsigned long rpmMicroMin = 0;     // Pulse minimum en microsecondes
const unsigned long rpmMicroMax = 400000;     // Pulse maximum en microsecondes

const int servoAngleMin = 0;     // Angle servo minimum
const int servoAngleMax = 90;     // Angle servo maximum

int servoAngle = 0;     // Angle mesuré

const unsigned long displayTempo = 500;     // Toutes les 1/2 secondes
unsigned long displayMillis = millis();     // Toutes les 1/2 secondes, chrono

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

	pinMode(rpmPin, INPUT_PULLUP);
}

void loop()
{
	rpmPulse = pulseIn(rpmPin, HIGH);
	//Serial.println(rpmPulse);

	servoAngle = map(rpmPulse, rpmMicroMin, rpmMicroMax, servoAngleMin, servoAngleMax);

	if (millis() - displayMillis >= displayTempo)     // Si moment d'afficher
	{
		Serial.println("Angle servo :\t" + String(servoAngle));
		displayMillis = millis();     // Redémarage du chrono
	}
}

A+
Cordialement
jpbbricole

Bonjour jef59.
Ce signal carré est traité ensuite par le tableau de bord pour indiqué le régime moteur.
Il n'a pas d'autre fonction.
Sans doute q'une impulsion correspond à 2 rpm.
En l’occurrence, sur ma moto, il n'y a pas de compte tour (pas vraiment utile) mais le pin existe car l'ECU Delphi MT05 est utilisé sur beaucoup d'autre moto.

Bonjour jpbbricole.
Merci pour ton aide, elle m'ai extrêmement précieuse!!
Je pense comprendre mieux le fonctionnement.
Mes première questions
A quoi sert le code:

const unsigned long displayTempo = 500;     // Toutes les 1/2 secondes
unsigned long displayMillis = millis();     // Toutes les 1/2 secondes, chrono

et

if (millis() - displayMillis >= displayTempo)     // Si moment d'afficher
	{
		Serial.println("Angle servo :\t" + String(servoAngle));
		displayMillis = millis();     // Redémarage du chrono

C'est accessoire, c'est simplement pour afficher périodiquement les valeurs, n'entre pas en jeu dans le programme principal.

Dans mon cas ou je ne possède pas d'ordinateur portable que je pourrais utiliser pour afficher les résultats en direct, moteur tournant et que ma compagne refuse que je démarre la moto dans le salon...(étrange mais elle a ses habitudes).
Effectivement cela ne m'est pas utile.

Ce n'est pas le nombre d'impulsions, mais sa durée que tu utilise avec le code de JPP qui m'interpelle, à priori elle semble 2 fois plus longue que prévue.

À 1600tr/mn, tu a une période qui est de 60/1600=37ms, et toi tu nous dis mesurer avec ton oscillo, au ralentit, 72ms, presque le double. à creuser.

Oui absolument j'ai écrit une bétise.
C'est le cycle qui dure 71,6 ms donc la durée de l'impulsion haute ou basse est de environ 31ms.

#include "Servo.h"

Servo servoclutch;

const int servoclutchPin = 12;
const int poussoirPin = 2;
const int neutralPin = 4;
const int rpmPin = 5;
unsigned long rpmPulse = 0;

const int servoAngleMin = 0;
const int servoAngleMax = 40;

const int rpmMicroMin = 0;
const int rpmMicroMax = 36000;

int servoAngle = 0;

void setup() 
{
  
  pinMode(poussoirPin, INPUT_PULLUP);
  pinMode(neutralPin, INPUT_PULLUP); 
  pinMode(rpmPin, INPUT_PULLUP);
  servoclutch.attach(servoclutchPin);
}

void loop() 
{
  while (digitalRead(poussoirPin) == HIGH)   
  {
    servoclutch.write(servoAngleMax);
   } 
  if (digitalRead(neutralPin) == HIGH)
  {
    servoclutch.write(servoAngleMin);
    }
   else
   {
     rpmPulse = pulseIn(rpmPin, HIGH);
  
     servoAngle = map(rpmPulse, rpmMicroMin, rpmMicroMax, servoAngleMin, servoAngleMax);

Voici mon code dans son ensemble avec la fonction pulseIn intégrée.
Je résume à nouveau le but recherché:
1)
si poussoir guidon fermé = position servo débrayé angle max (Cela me laisse une possibilité de débrayer manuellement).
2)
si interrupteur point mort fermé= position servo embrayé angle mini (Evite au servo de forcer pour rien)
3)
si aucune des conditions précitées n'est validée, la position du servo est gérer en fonction du régime moteur.

En théorie cela semble fonctionner...

J'avais une dernière question pour l'instant.
Est il cohérent d'écrire cela:

{
     rpmPulse = pulseIn(rpmPin, HIGH);
  if rpmPulse <= 26
     servoAngle = map(rpmPulse, rpmMicroMin, rpmMicroInter, servoAngleMin, servoAngleInter);
if rpmPulse > 26
     servoAngle = map(rpmPulse, rpmMicroInter, rpmMicroMax, servoAngleInter, servoAngleMax;
     }  

Le but serait de diviser la course de mon servo en 2 phases avec une phase plus "précise" que l'autre.

Bonjours,

Ça pourrait effectivement être plus ou moins "précis" en fonction des valeurs rpmMicroInter et servoAngleInter que tu choisis,

Tu ne nous as pas indiqué ces valeurs par contre.

Bonjour à tous.
Un grand merci à vous pour votre aide.
Voici le code "final" que je souhaite utiliser.

#include "Servo.h"

Servo servoclutch;

const int servoclutchPin = 12;
const int poussoirPin = 2;
const int neutralPin = 4;
const int rpmPin = 5;
unsigned long rpmPulse = 0;

const int servoAngleMin = 0;
const int servoAngleMax = 40;

const int rpmMicroMin = 28000;
const int rpmMicroMax = 36000;

int servoAngle = 0;

void setup() 
{
  
  pinMode(poussoirPin, INPUT_PULLUP);
  pinMode(neutralPin, INPUT_PULLUP); 
  pinMode(rpmPin, INPUT_PULLUP);
  servoclutch.attach(servoclutchPin);
}

void loop() 
{
  while (digitalRead(poussoirPin) == HIGH)   
  {
    servoclutch.write(servoAngleMax);
   } 
  if (digitalRead(neutralPin) == HIGH)
  {
    servoclutch.write(servoAngleMin);
    }
   else
   {
     rpmPulse = pulseIn(rpmPin, HIGH);
     if (rpmPulse > (rpmMicroMin))
    {    
    servoAngle = map(rpmPulse, rpmMicroMax, rpmMicroMin, servoAngleMin, servoAngleMax);
     }
     else
     {
       servoclutch.write(servoAngleMin);
  }
  }   
}

Cela devrait pourvoir me permettre d'adapter la course de mon servo (Max / Mini) selon une plage RPM de mon choix.
Malheureusement je n'arrive pas à trouver un moyen de le tester sur Tinkercad car je ne trouve pas d'outil capable de faire varier une durée d'impulsion.
J'attaque ma phase de montage sous peu.
Je prépare la commande de mes composants notamment pour mes diviseurs de tensions.
Je m'aperçois sauf erreur de ma part (ce qui est malheureusement probable) que le fait de réaliser un diviseur de tension sur mes entrée digitale avec une tension nominale max de 14,8V (R1=25kΩ / 0,5w et R2=10kΩ / 0,5w) sert aussi de PullUp puisque:

Bonjour louisduro

C'est plutôt une variation de fréquence?

Il y a le générateur de fonction:
image

Cordialement
jpbbricole

Super je ne savais pas que cela existait.
Je vais pouvoir tester. Merci!!

Bon j'ai tester un premier montage afin de valider ma rotation servo en fonction d'une variation de fréquence, mais rien ne se passe.
Lors de l'initialisation le servo se place sur 90 degres ( générateur de fonction on ou off), et rien d'autre...

Voici le code utilisé

#include "Servo.h"

Servo servoclutch;

const int servoclutchPin = 12;
const int rpmPin = 5;
unsigned long rpmPulse = 0;

const int servoAngleMin = 0;
const int servoAngleMax = 40;

const int rpmMicroMin = 0;
const int rpmMicroMax = 500;

int servoAngle = 0;

void setup() 
{
   
  pinMode(rpmPin, INPUT_PULLUP);
  servoclutch.attach(servoclutchPin);
}

void loop() 
{
  rpmPulse = pulseIn(rpmPin, HIGH);
    {    
    servoAngle = map(rpmPulse, rpmMicroMax, rpmMicroMin, servoAngleMin, servoAngleMax);
     }
  }
  

Une idée?

Bonsoir louisduro

Oui :wink:
Tu as:

const int rpmMicroMin = 0;
const int rpmMicroMax = 500;

Pour une fréquence de:
image
Ce qui fait ~40000 microsecondes.

Prends l'habitude, en cours de développement, de mettre des print dans tes programmes, ça aide à voire les erreurs.

#include "Servo.h"

Servo servoclutch;

const int servoclutchPin = 12;
const int rpmPin = 5;
unsigned long rpmPulse = 0;

const int servoAngleMin = 0;
const int servoAngleMax = 40;

const int rpmMicroMin = 0;
const int rpmMicroMax = 500;

int servoAngle = 0;

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

	pinMode(rpmPin, INPUT_PULLUP);
	servoclutch.attach(servoclutchPin);
}

void loop()
{
	rpmPulse = pulseIn(rpmPin, HIGH);
	{
		servoAngle = map(rpmPulse, rpmMicroMax, rpmMicroMin, servoAngleMin, servoAngleMax);
		Serial.println(rpmPulse);
	}
}

Cordialement
jpbbricole

Non, c'est un Pull-Down, il relie l'entrée de votre Arduino à "0" (Down) et non à 5V (High).
...

Conclusion:

C'est exacte, mais cela, c'est un "Pull-Down", donc si vous définissez cette entrée en INPUT-PULLUP, avec la résistance interne de PULLUP et R2, vous faites un pont diviseur et quand votre circuit est ouvert (s'il est ouvert?)

(5VxR2)/(R2+10k)=2,5V

Enlevez moi SVP votre éventuel "INPUT-PULLUP dans ce cas.

RAJOUT A MON MESSAGE:

En relisant vos post et en regardant votre code, je rajoute à mon post que sur la broche 5 que vous avez définit en

la conséquence est que lorsque votre générateur de fréquence de votre simulateur est Off

Rien n'assure que dans ce cas le simulateur considére que l'entrée soit "en l'air", peut-être qu'il la considére à 0V, dans ce cas le PULLUP soft ne sert à rien.

Mais effectivement si "générateur de fonction en Off" = entrée rpmPin en l'air (dans le cas de la simulation) alors avec le PULLUP interne cela crée l'entrée rpmPin = HIGH, et cela a de l'influence sur

Est-ce cela que vous cherchez?
A mon humble avis, je confirme, ne mettez pas l'entrée rpmPin en INPUT-PULLUP, mais uniquement en INPUT.

Je suggérerais d'utiliser le troisième argument de pulseIn() pour éviter de rendre ce code bloquant. Et de tester si la fonction retourne 0.
Voir ici

Bonjour Jef59.
Concernant mon précédant message j'aurais du le séparer en deux message distincts.
Mon problème de fonctionnement de code d'une part et ma réflexion sur l'aspect 2en1 d'un diviseur de tension dans le cadre d'une entrée en PULLUP avec bouton poussoir.
Circuit fermé (poussoir enfoncé) j'aurais bien 4,2v en entrée Pin2 et circuit ouvert (poussoir relaché) mon pin2 est bien relier au GND par l'intermédiaire de R2


J'ai réaliser une simulation en 9v cela me semble cohérent.
Mon diviseur de tension me permet de descendre ma tension d'entrée acceptable par l'Arduino et R2 "confirme" mon 0V
J'espère être claire....