Bonjour, j'ai pour pour projet d’améliorer le fonctionnement de mon vélo électrique dont le capteur de pédalage n'est pas suffisamment réactif.
Je sais qu'il y a déjà eu des montages similaires à ce que je souhaites faire, mais j'aimerai apprendre à le faire moi même en m'aidant de ce qui a déjà été fait.
Par exemple ici :
Ce sujet rejoint ce que je compte faire mais pas pour les mêmes raison.
J'ai remplacé récemment le contrôleur de mon vélo, mais le capteur de pédalage a un temps de réaction qui est désagréable à l'utilisation.
Il faut environ 3 tours de pédalier pour que l'assistance s'enclenche.
J'ai essayé plusieurs modifications depuis les réglages du contrôleur et en modifiant le capteur, mais rien n'y fait.
C'est bien le contrôleur qui crée cette latence sur l'entrée PAS.
En revanche le fonctionnement de l'accélérateur fonctionne parfaitement mais l'utilisation n'est plus celle d'un vélo mais plutôt d'un scooter.
Je souhaite utiliser l'Arduino pour collecter les impulsions +5v - 0v de mon capteur de pédalage pour les convertir en pseudo analogique afin de contrôler l'assistance électrique avec l'entrée Throttle ( accélérateur) du contrôleur.
J'ai commandé un Arduino Nano, je vais utiliser un petit potentiomètre 4.7K et un condo 50V 10MF pour filtrer le signal en sortie avec d'entrer dans le contrôleur.
Le schéma sera celui-ci.
J'attends mon Arduino d'ici quelques heures je pense que c'est à ma portée de débutant totalement ignorant dans le domaine.
J'ai compris que le Nano n'a pas de sortie analogique mais je devrais pouvoir m'en sortir en donnant des impulsions avec une fréquence bien adaptée permettant de faire fonctionner le signal de l'accélérateur du contrôleur.
J'ai téléchargé le soft Arduino IDE sur mon PC Ubuntu 18.04 LTS.
Je vais bientôt pouvoir passer à la partie programmation
Oui c'est ce que l'on peut dire, j'utilise un contrôleur Chinois avec afficheur LH 100.
Il fonctionne mais l'utilisation n'est pas à mon goût.
Je pense que le principe de l'Arduino sera parfait pour améliorer le fonctionnement.
En gros je cherche à piloter l'accélérateur via le pédalage.
C'est réinventer l'eau chaude puisque le contrôleur le fait déja mais en moins bien, du moins j'imagine.
Je ne connais pas ce contrôleur mais c'est toujours +/- la meme chose
AMHA (et c'est simple à tester ) il faut faire generer par l'aduino sur une sortie et à destination du PIN PAS, des créneaux 5V dont la récurrence est au au moins égal à la vitesse mini d'assistance ( tes 2/3 tours de pédaliers)
Non en faite je vais me servir du signal du capteur PAS pour l'envoyer à destination du signal de l'accélérateur à l'entrée du contrôleur. En faite je dois convertir le signal d'impulsion en entrée signal analogique. Comme l'Arduino Nano n'a pas de sortie Analogique il faudra jouer sur la longueur des créneaux pour simuler une sorte de signal analogique. Car si j'utilise l'entrée PAS du contrôleur pour la récéption du signal cela ne changera rien au problème de latence entre le début du pédalage et l'activation de l'assistance.
L'accélérateur lui est instantané dans sa réaction, il n'a aucun latence.
Ça n'a pas forcement besoin d'être hyper précis. d'envoyer environ 2V lorsque les impulsion données par le pédalier sont très lentes et 4,2V une fois que la cadence de pédalage est lancée.
Oui au niveau hardware j'ai essayé beaucoup de choses sur le PAS mais cela ne fait jamais baisser le temps de réaction entre la détection du pédalage et l'activation de l'assistance. Je suis même allé jusqu'à remplacer le capteur Hall récepteur par un simple capteur Reed et des aimants de porte de placards. Cela fonctionne mais ne change rien, il faut toujours environ 2 sec pour que l'assistance s'active ou 1,5 (dans le meilleur des cas ) à 3 tours de pédaliers. Actuellement j'utilise toujours ce montage qui donne un signal très binaire sur le signal PAS.
Je peux faire rouler le vélo même en rétro-pédalage puisque j'ai viré le capteur d'origine qui empêche cela .
Cette latence fait partie du fonctionnement normal de ce contrôleur et ne peut être résolue qu'en modifiant le programme natif.
La partie du programme accessible depuis l'afficheur LCD ne permet pas de réduire cette latence non plus.
Voilà pourquoi je souhaite utiliser l'Arduino.
Autant vous dire que le vélo reste tout à fait utilisable et présente simplement un aspect désagréable minime à l'utilisation. Résoudre ce problème avec un Arduino est surtout une façon relativement simple de trouver une application utile pour que je débute dans ce domaine. Il serait plus simple de remplacer le contrôleur par un modèle qui répond mieux à mon attente, mais je trouve cela bien moins amusant et quelque peu du gâchit, car hormis cela le contrôleur fonctionne parfaitement.
Pour en revenir à nos moutons, j'ai reçu mon petit Nano et des fils Dupont mais pas encore le kit débutant que j'ai commandé avant hier.
Il vient de Chine donc il lui faudra un peu de temps.
Je voudrais savoir un chose.
Est-il possible de téléverser un programme avant de faire un montage même très sommaire ?
J'ai suivi le tuto Blink mais mon Nano me donne un message d'erreur lors du téléversement, pourtant le retour de la vérification du code est bonne.
J'ai ce qu'il faut pour faire un petit montage sommaire à led, mais il me manque la plaque Labdec (ce terme me rappel ma 1er année BEP électro-tech ).
Le Nano est bien reconnu par mon PC et j'ai réglé les paramètres sur le bon Port avec l'option Nano, et processeur ATmega328P. (ça correspond bien à ce qui est écrit dessus aussi)
Sur la boite je vois écrit CH340 peut-être que mon problème vient de là ?
Arduino : 1.8.19 (Linux), Carte : "Arduino Nano, ATmega328P"
Le croquis utilise 924 octets (3%) de l'espace de stockage de programmes. Le maximum est de 30720 octets.
Les variables globales utilisent 9 octets (0%) de mémoire dynamique, ce qui laisse 2039 octets pour les variables locales. Le maximum est de 2048 octets.
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x00
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x00
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x00
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x00
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x00
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x00
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x00
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x00
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x00
Une erreur est survenue lors du transfert du croquis
Ce rapport pourrait être plus détaillé avec
l'option "Afficher les résultats détaillés de la compilation"
activée dans Fichier -> Préférences.
Pour l'instant je n'ai fais que traduire les lignes d'explications en Français pour m'aider à comprendre comment le programme est fait.
J'ai aussi modifié les constantes matérielles que je compte mettre :
_ Le PAS sur l'entrée 9.
_ La LED de contrôle sur le PIN 11
_ La broche de sortie PWM accélérateur sur 13
// constantes matérielles
const int PASPin = 9; // entrée venant du PAS
const int ledPin = 11, PWMOut=13; // Broche à laquelle la LED est attachée et la broche de sortie PWM
// constantes du logiciels
const unsigned long activityTimeoutMS = 500; // Temps d'inactivité du signal PAS autorisé avant de s'éteindre
const int startPulses = 2; // Nombre d'impulsions PAS nécessaires avant la mise en marche
const int lowPWMValue = 56, highPWMValue = 170; // Valeurs PWM pour piloter l'entrée de l'accélérateur, par défaut 56 (1,1 V) et 170 (3,4 V), U=n/255*5V, n=U/5V*255
// Variables
volatile int inputEdges = 0; // compteur du nombre d'impulsions depuis la dernière remise à zéro
volatile unsigned long lastEdgeTime = 0; // horodatage de la dernière impulsion PAS
bool state=false; // variable contenant des informations sur l'état de la sortie
void setup() {
pinMode(PASPin, INPUT); // initialiser la broche PAS comme entrée
attachInterrupt(digitalPinToInterrupt(PASPin), pulse, RISING); //Chaque front montant sur la broche PAS provoque une interruption
pinMode(ledPin, OUTPUT); // initialiser la LED en tant que sortie
pinMode(PWMOut, OUTPUT); // initialiser la broche PWM en tant que sortie
}
void loop() {
//Si le signal PAS est inactif trop longtemps, éteignez tout
unsigned long curTime=millis();
if ((curTime>lastEdgeTime)&&((curTime-lastEdgeTime)>activityTimeoutMS)) {
turnOff();
}
//Si le système est éteint, vérifier si les impulsions sont actives
if ((!state)&&((millis()-lastEdgeTime)<activityTimeoutMS)) {
//si les impulsions sont actives, vérifiez s'il y avait suffisamment d'impulsions pour allumer
if (inputEdges>startPulses) {
turnOn();
}
}
J'avoue que même si j'avais compris comment programmer l'Arduino pour convertir le signal PAS en PWM pour l'accélérateur, je n'aurais sûrement pas pensé à mettre une fonction d'arrêt automatique ou de démarrage automatique du système.
Je vais donc commencer par régler l'Arduino simplement comme je l'aurais fait juste pour les signaux entrée et sortie.
Je modifierai le programme au fur et à mesure de mes essais pour comprendre exactement chaque fonctions.
Bonjour on m'a fait remarqué que j'ai fais une belle erreur avec la petite modification que j'ai fais sur les constantes.
Il faut que je réaffecte les entrées/sorties telles qu'elles étaient à l'origine car ça ne va pas. En plus j'ai confondue les numéros et le noms des PIN. Je ne savais pas que les interrupt etaient limitée sur l'Arduino à 2 PIN et les sorties ne vont pas non plus.
Finalement j'ai procédé au téléversement du croquis fonctionnel et j'ai fais le montage sur mon vélo. Ça fonctionne presque parfaitement. J'utilise actuellement l'alim 4.2V du vélo pour alimenter l'Arduino sur le PIN +5V. C'est trop faible pour l'Arduino et mauvais pour le contrôleur.
J'ai fais quelques petites vidéos pour vous montrer ce que j'ai déjà fait.
Du coup je suis passé sur l'alim de la lumière du vélo qui est en 6 vdc et j'alimente l'Arduino en Vin.
Il y a un petit problème de fonctionnement comme-ci l'Arduino ne voyait pas toutes les impulsions entrantes.
J'ai essayé plusieurs réglages des variables mais cela ne change rien.
A priori il y a une erreur dans le code du PAS du coup je vais modifier cela.
Voici le dernier code que j'ai téléversé, il fonctionne parfaitement, le code de base présentait quelques petits manque dans la captation du signal venant du capteur de pédalage, ce qui entrainait des coupures d'assistance intempestive.
De plus il manquait une resistance sur l'entrée PAS qui a été inclue dans le code en INPUT_PULLUP
// constantes matérielles
const int PASPin = 2; // entrée venant du PAS
const int ledPin = 13, PWMOut=10; // Broche à laquelle la LED est attachée et la broche de sortie PWM
// constantes du logiciels
const unsigned long activityTimeoutMS = 500; // Temps d'inactivité du signal PAS autorisé avant de s'éteindre
const int startPulses = 7; // Nombre d'impulsions PAS nécessaires avant la mise en marche
const int lowPWMValue = 54, highPWMValue = 252; // Valeurs PWM pour piloter l'entrée de l'accélérateur, par défaut 56 (1,1 V) et 170 (3,4 V), U=n/255*5V, n=U/5V*255
// Variables
volatile int inputEdges = 0; // compteur du nombre d'impulsions depuis la dernière remise à zéro
volatile unsigned long lastEdgeTime = 0; // horodatage de la dernière impulsion PAS
bool state=false; // variable contenant des informations sur l'état de la sortie
void setup() {
pinMode(PASPin, INPUT_PULLUP); // initialize the PAS pin as a input (pullup !)
attachInterrupt(digitalPinToInterrupt(PASPin), pulse, RISING); //Each rising edge on PAS pin causes an interrupt
pinMode(ledPin, OUTPUT); // initialize the LED as an output
pinMode(PWMOut, OUTPUT); // initialize the PWM pin as an output
}
void loop() {
//Si le signal PAS est inactif trop longtemps, éteignez tout
unsigned long curTime=millis();
if ((curTime>lastEdgeTime+400)&&((curTime-lastEdgeTime)>100)) {
turnOff();
}
//Si le système est éteint, vérifier si les impulsions sont actives
if ((!state)&&((millis()-lastEdgeTime)< activityTimeoutMS)) {
//si les impulsions sont actives, vérifiez s'il y avait suffisamment d'impulsions pour allumer
if (inputEdges>startPulses) {
turnOn();
}
}
//Utilisation LED pour l'état
digitalWrite(ledPin, state);
}
//Turn off output, reset pulse counter and set state variable to false
void turnOff() {
detachInterrupt(digitalPinToInterrupt(PASPin)); // desactiver interrupt, uniquement pin concernée
analogWrite(PWMOut, lowPWMValue);
inputEdges = 0;
state = false;
attachInterrupt(digitalPinToInterrupt(PASPin), pulse, RISING); // reactiver interruption
}
//Activer la sortie et définir la variable d'état sur vrai
void turnOn() {
analogWrite(PWMOut, highPWMValue);
state=true;
}
//Interrompre le sous-programme, actualiser l'horodatage de la dernière impulsion et incrémenter le compteur d'impulsions (jusqu'à ce que 10000 soit atteint)
void pulse() {
lastEdgeTime=millis();
if (inputEdges< 100) {
inputEdges++;
}
}