Bref, les compteurs de vélos (odomètre capteur magnet KY03) qui mesurent la vitesse grâce à un compte tour de la roue pourrait aussi mesurer la décélération et activé un STOPT arrière.
Mais quelle pourrait être la précision de cette méthode ? Faut-il mettre plusieurs aimants sur la roue ? Faut-il filtrer la valeur de la décélération ?
De plus, il existe des éclairages arrière vélos qui donnent la direction (clignotant droit et gauche) sans fil, mais sur un vélo, il n'y qu'à tendre la main à droite ou à gauche donc c'est inutile.
Mais pour un velomobile (vélo caréné), cela est intéressant
http://velorizontal.1fr1.net/t17956-velomobile-electric-leiba-x-stream-iut-aisne
Voici un bel article avec 2 arduinos et une communication bluetooth
https://create.arduino.cc/projecthub/simonwongwong/bluetooth-enabled-bicycle-turn-signal-2f4f5dMais les matrices de leds ne permettent pas d'être vu de jour (pas assez de lumen)
L'article suivant utilise une télécommande 4 boutons
https://github.com/sdebby/Arduino_bike_blinkDonc une télécommande et un récepteur, voici en voici l'électronique
http://www.wzmicro.com/rf.htmCela ne coute rien, mais il faudra mettre le compteur de vélo sur l'Arduino arrière pour avoir un feu stop

Donc, un compteur vélo avec Bluetooth va être réalisé et commander l'éclairage arrière comme on peut l'observer sur la figure suivante.
Le compteur avec son afficher a permis de vérifier le bon fonctionnement de la programmation et s'il fallait filtrer la mesure de la décélération
Il faudra prendre des Arduino Pro et pas nano pour leurs faibles consommations sur la batterie.
Mais pour vérifier la programmation le nano a été utilisé.

L'indication droite et gauche est évidemment clignotante ainsi que le stop et lors de la décélération.
Mais on aurait pu mettre une 4éme led, pour un feu stop mais cela n'a pas été fait.
Le bouton poussoir stop est inutile, puisque la décélération est mesurée et active automatiquement l'éclairage arrière.
Le compteur vélo a 4 aimants sur la roue pour augmenter la précision des mesures de la vitesse dans les basses vitesses.
Avec l'utilisation de la mesure en milliseonde à chaque quart de roue
L'erreur de la vitesse est déterminée par l'équation suivante avec 4 aimants
DeltaVitesse=(2010*3.6/4)/(Timer+1)( Timer) pour Timer=25ms=>2.78km/h pour vitesse 72km/h
La précision correspond à l'équation suivante
Précision=1/(Timer+1) donc à 72km/h précisons de 3.8% et à 18km/h 1%
Etant donné que l'accélération est déterminée aussi pour chaque quart de roue tournée, l'erreur de l'accélération correspondra aux équations suivantes
DeltaAccelera=(277)/(Timer+1)( Timer) pour Timer=25ms=>0.42m/s^2 pour vitesse 72km/h
DeltaAccelera=(277)/(Timer+1)( Timer) pour Timer=100ms=>0.027m/s^2 pour vitesse 18km/h
Pour ne pas avoir de décélération intempestive, le calcul de la décélération se fera seulement si l'erreur de mesure de la vitesse est plus faible que sa variation.
Etant donné que la propriété de la routine d'interruption extérieure n'est pas si facile à imposer par rapport à routine d'interruption timer sur Atmel, il n'y aura pas d'interruption timer.
Voici le code
#include <LiquidCrystal.h>
#include <SoftwareSerial.h>
//#include <TimerOne.h>
#define led13 13 //
#define BPLeft 12 //
#define Night 11 //
#define BPRight 10 //
#define BPStop 9 //
LiquidCrystal lcd(8, 3, 4, 5, 6, 7); // LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
// Configuration des variables
float Time=0;
float TO=0;
float temps=0;
float Time1=0;
float kph=0;
float kph1=0;
float distance=0;
float deceler=0;
float erreur=0;
bool stop=0;
bool flagnight=0;
bool attendre=0;
byte buffer1=0;
String readString;
// the setup function runs once when you press reset or power the board
void setup() {
pinMode(led13, OUTPUT); //led carte arduino
pinMode (BPLeft, INPUT_PULLUP);
pinMode (Night, INPUT_PULLUP);
pinMode (BPRight, INPUT_PULLUP);
pinMode (BPStop, INPUT_PULLUP);
lcd.begin(16, 2); //modifier pour un afficheur 20x4
Serial.begin(9600); //57600
//SoftwareSerial mySerial(0, 1); // RX, TX mais il n'y a pas trop le choix sur la nano
// Timer1.initialize(10000); // initialize timer1, and set a 0,1 second period => 100 000 pour 0.01s 10 000
// Timer1.attachInterrupt(Routinetimer1); // attaches le sous programme Routinetimer1 as a timer overflow interrupt
TCCR2B = (TCCR2B & 0b11111000) | 0x01; //pin 3 32khz
attachInterrupt(0, interrup2, RISING); // il vaut mieux utiliser KY003 tout ou rien RISING, FALLING, CHANGE
TO = millis();
}//fin setup
void interrup2() // la fonction appelée par l'interruption externe n°0
{//digitalWrite(led13,HIGH);
Time=(millis()-TO); //mesure du temps //micros() millis()
TO=millis();
distance=(distance+(2.01/4)); //perimetre/4 aimants
kph1=kph;
if (Time>=500) {kph=0;deceler=0; }
else {kph=((2.010*1000*3.6)/(Time*4)); //kph=perimetre/time avec 4 aimants //
erreur=(kph/(Time-2));
if ( (kph<(kph1-erreur))) {deceler=(((kph-kph1)*277)/Time);} else {deceler=0;}
} // en m/s^2 277=1000milliseconde/3.6
if (deceler<-40) {deceler=-40; }
if (deceler>40) {deceler=40; }
// digitalWrite(led13,LOW); de la routine interr exterieur durée 0.7ms
}
// Interruptions tous les 100ms fait par le timer1***********************************
//void Routinetimer1() {
// temps++;
//}//fin routineinterruption
///////////////////////////////////////////// Boucle correspondant à la fonction main
void loop() {
Time1=(millis()-TO);
if (Time1>=500) {kph=0;deceler=0;} //remise à 0, lorsqu'il n'y a plus d'interruption
attendre=0;
lcd.setCursor(0,0); // (X,Y)
lcd.print(kph,1);
lcd.print("kph ");
lcd.setCursor(9,0); // (X,Y)
lcd.print(distance/1000,2);
lcd.print("km ");
lcd.setCursor(0,1); // (X,Y)
lcd.print(deceler,1);
lcd.print("m/s");
lcd.print((char)94);
lcd.print("2 ");
if (deceler<(-2)) {stop=1;lcd.setCursor(10,1);lcd.print("STOP");Serial.print(2); }
if (deceler>0) {stop=0,lcd.setCursor(10,1);lcd.print(" "); }
if (digitalRead(BPStop)==0) {stop=1;lcd.setCursor(10,1);lcd.print("STOP");Serial.print(2); }
if (digitalRead(BPLeft)==0) {Serial.print(1); }
if (digitalRead(BPRight)==0 ) {Serial.print(3); }
if (digitalRead(BPRight)==0 && digitalRead(BPStop)==0 ) {distance=0;} //remise à zero du compteur
if (digitalRead(BPStop)==0) {stop=1;lcd.setCursor(10,1);lcd.print("STOP");Serial.print(2); }
if ((digitalRead(Night)==0) && (flagnight==0) && attendre==0 ) {flagnight=1;Serial.print(0);attendre=1; } //eteindre la lumiere
if ((digitalRead(Night)==0) && (flagnight==1) && attendre==0) {flagnight=0;Serial.print(4);attendre=1;} //allume lumiere
if (flagnight==1) {lcd.setCursor(15,0);lcd.print("N"); } //lumiere
if (flagnight==0) {lcd.setCursor(15,0);lcd.print(" "); }
/*Serial.print(Time,0);
Serial.print(";");
Serial.print(kph,1);
Serial.print(";");
Serial.print(deceler,1);
Serial.println(";"); */
delay(100);
} // fin loop