/*******************************************************************************************/
// PROGRAMME GESTION VELO VAE PLIANT - VERSION 2 //
// //
// JUIN 2016 //
/*******************************************************************************************/
// Martial LEYNEY
// 14/06/2016
// Projet Vlo VAE Pour B-FOLD pliant
// Gestion vitesse de pdalage (par interruption)
// Gestion PWM pour variation puissance moteur
// Regulation PI en puissance moteur
// Transfert des infos en bluetooth vers IHM Android
/*******************************************************************************************/
#include <SoftwareSerial.h>
#include <avr/wdt.h> //watchdog
#include <math.h>
/*******************************************************************************************/
//Entres Interruptions
#define INT_BPMode 2 //entree bouton poussoir fonction MODE ASSISTANCE sur pin DIG2
#define INT_Pedalage 3 //entree detection rotation pdalier sur pin DIG3
//Entres/sorties logiques C
#define MotPin 5 //sortie PWM vers controleur moteur Brushless
#define LEDLEVEL_M A4 //sortie LED Orange Niveau assistance MIDDLE
#define LEDLEVEL_L 7 //sortie LED Orange Niveau assistance LOW
#define CMD_FEUX 4 //sortie de commande phare avant et feux arrieres
#define SW_CTRLMOT 6 //commande switch Controleur Moteur
#define LEDALERT A2 //Tmoin LED rouge ALERTE/ERREUR
#define LEDBAT_R 9 //sortie LED RGB cmd rouge
#define LEDBAT_G 10 //sortie LED RGB cmd vert
#define LEDBAT_B 11 //sortie LED RGB cmd bleu
#define RST_BT 8 //Reset module bluetooth
//ADC
#define Imot A0 //entre analogique image courant moteur
#define Vmot A1 //entre analogique image tension moteur
#define TempBat A3 //entre analogique image temperature pack batterie (Thermistance CTN VISHAY NTCLE213E3103FHB0 10Kohms 1%)
#define PhotoR A5 //entre analogique image luminosit extrieure (LDR NSL4962)
/*******************************************************************************************/
//definitions
//PARAMETRAGE VELO *** A MODIFIER ***
//#define PEDALAGE_DEMARR 2110 //Periode capteur max pour condition de demarrage (environ 1km/h)
#define PEDALE_COMPTEUR_SEUIL 3 // Compteur de filtrage pour capteur de rotation pdalier
#define PEDALAGE_TMAX 422 //Periode capteur max sinon "pas de pedalage" (12 periodes capteur = 1 tour pedalier) (correspond a environ 3.5km/h)
#define PEDALAGE_DISTCM 478 //longueur au sol en cm pour un tour de pedalier
#define TBATTMAX 70 //Temperature max du pack batterie en C
#define VBATTMIN 145 //seuil mini tension batterie
#define VBATTMAX 892 //seuil maxi tension batterie
#define ASSIST_M 190 //Consigne d'assistance en Watts Niveau Medium ****** A DEFINIR ******
#define ASSIST_L 110 //Consigne d'assistance en Watts Niveau Low ****** A DEFINIR ******
#define ASSIST_0 0 //Arret assistance
#define LUX_SEUIL 580 //Seuil de luminosite allumage Feux Av et AR (- sensible si valeur + grande)
/*******************************************************************************************/
//variables globales
char erreur = 0; //gestion d'erreur systeme
// =0 si pas d'erreur,
//bit 0=1 si pas de pedalage,
//bit1=1 si ...,
//bit2=1 si ...,
//bit3=1 si ...,
//bit4=1 si pb batterie principale,
//bit5=1 si ...,
//bit6=1 si Pb communication Bluetooth
//bit7=1 si Pb temperature Pack batterie
unsigned long Tpedalage; //vitesse de pedalage en msec
unsigned long VitVelo; //vitesse du velo en km/h x10 (pour affichage)
unsigned int MoyVitVelo[4]; //vitesse moyenne sur 1/3 tour de pedalier
unsigned int AffVitVelo = 0; //vitesse moyenne de pdalage pour affichage appli android
volatile unsigned long Tcapteur, Tcapteurm1; //calcul periode capteur sur axe pedalier
int LevelAssist; //consigne d'assistance de rfrence selon choix utilisateur
float Ukm2, Ukm1, Uk, Ekm2, Ekm1, Ek; //variables pour correcteur
float Cons_Wmot; //consigne de puissance lectrique envoy au moteur apres prise en compte vitesse de pdalage
float Mes_Wmot; //puissance consomme par moteur
unsigned int MoyMesWmot[12]; //Puissance moyenne mesure sur 1 tour de pedalier
unsigned int AffMesWmot = 0; //Mesure Puissance moyenne pour affichage appli android
int Iref; //valeur de reference pour mesure courant moteur
int MotMoy[5]; //buffer pour lissage sortie moteur
boolean refresh; //demande de maj mesure (true si besoin)
boolean flagMode; //drapeau appui BP utilisateur
int Vbatt, Tbatt; //tension image ACD pour pack batterie
int BatMoy[5]; //buffer pour lissage tension batterie
//variables pour mesure temperature pack batterie
const unsigned char tableHr[] = {0, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 99};
const int tableHrADC[] = {0, 4, 10, 18, 45, 72, 199, 324, 467, 608, 702, 797, 852, 905, 934, 963, 983, 1023};
//Liaison serie Bluetooth RN42
SoftwareSerial IHMSerial(13, 12); // RX, TX bluetooth IHM
/*******************************************************************************************/
char gestion_Pedalage(void);
void gestion_moteur(int w);
void gestion_BT(void);
void gestion_LEDMode(int v);
void gestion_LEDbatt(int v);
unsigned char gestion_erreur(void);
/*******************************************************************************************/
void setup()
{
char a, b;
//init E/S
pinMode(INT_BPMode, INPUT); //entree interruption bouton poussoir selection assistance par utilisateur
pinMode(INT_Pedalage, INPUT); //entree interruption detection rotation pdalier
pinMode(MotPin, OUTPUT);
pinMode(LEDLEVEL_M, OUTPUT);
pinMode(LEDLEVEL_L, OUTPUT);
pinMode(CMD_FEUX, OUTPUT);
pinMode(SW_CTRLMOT, OUTPUT);
pinMode(LEDALERT, OUTPUT);
pinMode(LEDBAT_R, OUTPUT);
pinMode(LEDBAT_G, OUTPUT);
pinMode(LEDBAT_B, OUTPUT);
pinMode(RST_BT, OUTPUT);
//
Serial.begin(115200); //init UART
//init interruptions
attachInterrupt(1, IRQ_Pedalage, FALLING); //interruption n1 (pin DIG3) sur front descendant
attachInterrupt(0, IRQ_BPMode, FALLING); //interruption n0 (pin DIG2) sur front descendant
//init des entres/sorties et periphriques
analogWrite(MotPin, 0); //arret moteur au cas o...
//digitalWrite(RST_BT, LOW); //RESET du module Bluetooth ????
digitalWrite(LEDLEVEL_M, LOW);
digitalWrite(LEDLEVEL_L, LOW);
digitalWrite(CMD_FEUX, LOW);
digitalWrite(SW_CTRLMOT, LOW);
digitalWrite(LEDBAT_R, HIGH);
digitalWrite(LEDBAT_G, HIGH);
digitalWrite(LEDBAT_B, HIGH);
//Init sofware serial pour liaison bluetooth IHM
digitalWrite(RST_BT, LOW); //RESET bluetooth
delay(100);
digitalWrite(RST_BT, HIGH);
delay(100);
IHMSerial.begin(115200); // The Bluetooth Mate defaults to 115200bps
IHMSerial.print("$"); // Print three times individually
IHMSerial.print("$");
IHMSerial.print("$"); // Enter command mode
delay(100); // Short delay, wait for the Mate to send back CMD
IHMSerial.println("U,9600,N"); // Temporarily Change the baudrate to 9600, no parity
IHMSerial.begin(9600);
//init variables
refresh = true;
LevelAssist = ASSIST_L;
gestion_LEDMode(LevelAssist); //maj affichage
Tpedalage = 0;
Tcapteur = 0;
Tcapteurm1 = 0;
Cons_Wmot = 0;
for (a = 0; a < 5; a++) {
MotMoy[a] = 0;
}
VitVelo = 0;
for (a = 0; a < 4; a++) {
MoyVitVelo[a] = 0;
}
for (a = 0; a < 12; a++) {
MoyMesWmot[a] = 0;
}
//automatisation du dmarrage systme
delay(200);
digitalWrite(SW_CTRLMOT, HIGH); //activation automatique controleur moteur brushless
delay(200);
//Animation LED + mesure courant au repos
Iref = 502; //TEST : Valeur Fixe 502 car la mesure ci-dessous apportait des imprecisions (delta de 25W selon les allumages)
//Iref = 0;
gestion_LEDbatt(300);
delay(150);
//Iref += analogRead(Imot); //recup valeur courant de reference avec moteur arret
gestion_LEDbatt(600);
delay(150);
//Iref += analogRead(Imot); //recup valeur courant de reference avec moteur arret
gestion_LEDbatt(800);
delay(150);
//Iref += analogRead(Imot); //recup valeur courant de reference avec moteur arret
gestion_LEDbatt(1000);
delay(150);
//Iref /= 3; //moyennage du courant de repos
//Serial.print("IREF = ");
//Serial.println(Iref);
//Premiere mesure tension batterie l'arret
Vbatt = analogRead(Vmot); //recup valeur
for (a = 0; a < 5; a++) {
BatMoy[a] = Vbatt; //raz moyenne tension batterie
}
if ((Vbatt >= VBATTMIN) && (Vbatt <= VBATTMAX)) {
bitClear(erreur, 4);
} else {
bitSet(erreur, 4);
}
gestion_LEDbatt(Vbatt); //maj affichage
//Init ok
digitalWrite(LEDALERT, LOW);
//activation watchdog
wdt_enable(WDTO_2S);
}
/*******************************************************************************************/
void loop(void)
{
static int bcl = 0; //"static" car sinon on perd la valeur a chaque retour de boucle
unsigned long timeMOT; //instant ou on applique une consigne moteur
unsigned long tm;
char a;
int mesureW;
int lux;
//PRISE INFO PEDALAGE
if (gestion_Pedalage() == 0) { // *** pedalage en cours***
//maj variables dans sous-fonction OK
//surveillance tension batterie en fonctionnement (tt les 2 secondes)
if (bcl++ == 40) {
Vbatt = 0;
for (a = 0; a < 4; a++) {
BatMoy[a] = BatMoy[a + 1]; //decalage 5 dernieres mesures
}
BatMoy[4] = analogRead(Vmot); //recup valeur
for (a = 0; a < 5; a++) {
Vbatt += BatMoy[a]; //moyenne tension batterie
}
Vbatt /= 5;
if ((Vbatt >= VBATTMIN) || (Vbatt <= VBATTMAX)) {
bitClear(erreur, 4);
} else {
bitSet(erreur, 4);
}
gestion_LEDbatt(Vbatt); //maj affichage
bcl = 0;
}
//
refresh = true; //demande de maj mesures au prochain arret de pedalage
bitClear(erreur, 0);
}
else { // *** pas de pedalage ***
//GESTION NIVEAU ASSISTANCE (BP MODE)
if (flagMode == true) {
delay(500);
if (digitalRead(INT_BPMode) == LOW) { //appui long pour anti-rebond par vibration route
if (LevelAssist == ASSIST_0) {
LevelAssist = ASSIST_L;
}
else if (LevelAssist == ASSIST_L) {
LevelAssist = ASSIST_M;
}
else if (LevelAssist == ASSIST_M) {
LevelAssist = ASSIST_0;
}
else { //en cas de pb...
LevelAssist = 0;
}
gestion_LEDMode(LevelAssist); //maj affichage
}
flagMode = false;
}
//Suite un arret de pdalage (1 seule fois) : On en profite pour faire un rafraichissement des infos
if (refresh == true) {
//GESTION TEMPERATURE PACK BATTERIE
float TempP = Thermistor(analogRead(TempBat)); //recup valeur temperature en degr celcius
//Ajustage supplementaire selon talon
TempP -= 1;
if (TempP < 0) TempP = 0; //bornage
if (TempP >= 100) TempP = 99; //bornage
Tbatt = (int)TempP;
if (Tbatt <= TBATTMAX) {
bitClear(erreur, 7);
} else {
bitSet(erreur, 7);
}
//GESTION ECLAIRAGE SELON LUMINOSITE
lux = analogRead(PhotoR);
if (lux >= LUX_SEUIL) {
digitalWrite(CMD_FEUX, HIGH); //Allumage des feux AV et AR
} else {
digitalWrite(CMD_FEUX, LOW); //Extinction des feux AV et AR
}
//
refresh = false; //une seule demande
}
bitSet(erreur, 0);
}
//GESTION MOTEUR
if ((gestion_erreur() == 0) && (bitRead(erreur, 0) == 0)) { //pas d'erreur majeure ET pedalage en cours
gestion_moteur(LevelAssist); // application moteur de la consigne utilisateur
} else { //Sinon...
//RAZ
VitVelo = 0;
for (a = 0; a < 4; a++) {
MoyVitVelo[a] = 0;
}
AffVitVelo = 0;
for (a = 0; a < 5; a++) {
MotMoy[a] = 0;
}
gestion_moteur(0); //ARRET moteur
}
//GESTION INFOS IHM (liaison bluetooth)
gestion_BT(); //check si ordre recu de l'IHM
//CADENCEMENT BOUCLE
delay(50);
//RESET WATCHDOG
wdt_reset();
//
}
/*******************************************************************************************/
//interruption par entre INT_RxPedale (dig2)
void IRQ_BPMode()
{
flagMode = true;
}
/*******************************************************************************************/
//interruption par entre INT_Pedalage (dig3)
void IRQ_Pedalage()
{
Tcapteurm1 = Tcapteur;
Tcapteur = millis();
}
/*******************************************************************************************/
//Detection pdalage et calcul vitesse de pedale (vitesse vlo en km/h)
// renvoie 0 si pdalage + maj "Tpedalage"
char gestion_Pedalage(void) {
char a;
unsigned long timeout;
static byte pedale_compteur = 0;
timeout = millis();
cli();
timeout -= Tcapteurm1;
Tpedalage = Tcapteur - Tcapteurm1;
sei();
//bitSet(EIFR, INTF1); //raz flag interruption (on laisse dans le doute)
//bitSet(EIFR, INTF0);
if (Tpedalage < PEDALAGE_TMAX && timeout < (PEDALAGE_TMAX + 200)) //Vitesse trop lente ou creneau capteur trop ancien (arret de pedalage)
{
//tampon filtrage des tats
if (pedale_compteur < 2 * PEDALE_COMPTEUR_SEUIL)
pedale_compteur++;
}
else
{
//tampon filtrage des tats
if (pedale_compteur > 0)
pedale_compteur--;
}
if (pedale_compteur < PEDALE_COMPTEUR_SEUIL) //Etat d'arret de pedalage
{
Tpedalage = PEDALAGE_TMAX;
VitVelo = 0;
return 1; //PAS DE PEDALAGE
}
else
{
//calcul vitesse de pedalage + periode
Tpedalage *= 12;
VitVelo = 36 * PEDALAGE_DISTCM;
VitVelo *= 10;
VitVelo /= Tpedalage;
//TEST 06/10/2016: Moyennage vitesse pour affichage plus stable sur appli Android
if(VitVelo > 350) VitVelo = 350;
//Moyenne vitesse sur 1/2 tour complet de pdalier (4 dernieres valeurs)
for (a = 0 ; a < 3 ; a++) { //decalage
MoyVitVelo[a] = MoyVitVelo[a + 1];
}
MoyVitVelo[3] = (unsigned int) VitVelo;
AffVitVelo = 0;
for (a = 0 ; a <= 3 ; a++) { //calcul moyenne
AffVitVelo += MoyVitVelo[a];
}
AffVitVelo /= 4;
return 0; //PEDALAGE EN COURS
}
}
/*******************************************************************************************/
//application tension sur moteur via PWM (moyenn par filtre RC en sortie)
//@param: w = watt a fournir
//De 0 20km/h: 1W electrique = 1W humain
//l'assistance lectrique dcroit progressivement de 20km/h 25km/h pour tre nulle au del de 25km/h (developpement court sur velo pliant...)
void gestion_moteur(int w) {
char a;
int pwm;
int val1, val2;
float u, i;
//digitalWrite(OutTest, HIGH); //pour mesure temps de traitement (env 390s)
noInterrupts();
//bornage
if (w < 0) w = 0;
if (w > 255) w = 255;
//correction selon vitesse
if (VitVelo < 10) {
pwm = 0;
}
else if (VitVelo < 200) {
pwm = w;
}
else if (VitVelo < 250) {
pwm = 250 - VitVelo;
pwm *= w;
pwm /= 50;
}
else {
pwm = 0;
}
//lissage sur les 5 dernieres valeurs
for (a = 0; a < 4; a++) {
MotMoy[a] = MotMoy[a + 1]; //backup
}
MotMoy[4] = pwm; //MAJ
pwm = 0;
for (a = 0; a < 5; a++) {
pwm += MotMoy[a];
}
Cons_Wmot = (float)(pwm / 5); //Moyennage sur 5 valeurs
//
// **** Regulation PI selon consigne w **** //
//Mesure puissance moteur via LEM + conversion en W
val1 = analogRead(Imot);
val2 = analogRead(Vmot);
//bornage
if (val1 < Iref) val1 = Iref;
//calcul tension batterie
//ampli diff : 3.09 x (Vi - Vref) avec Vi = Vbat/8.5 et Vref = 3.53V
//coeff CAN : 1024 / 5
u = (float)((42.5 * val2) / 3164.16);
u += 30, 2; // + correction 200mV
//calcul courant mesure
val1 -= Iref; //offset LEM
i = (float)val1 * 5; //coeff CAN
i /= 1024; //
i /= 0.0625; //coeff LEM
Mes_Wmot = u * i; //puissance mesure
//maj et moyennage mesure pour affichage
for(a = 0; a < 11; a++){
MoyMesWmot[a] = MoyMesWmot[a+1];
}
float m = Mes_Wmot;
MoyMesWmot[11] = (int)m;
AffMesWmot = 0;
for(a = 0; a < 12; a++){
AffMesWmot += MoyMesWmot[a];
}
AffMesWmot /= 12; //maj mesure moyenne sur 1 tour pour affichage appli android
/*
Serial.print("u="); //DEBUG
Serial.println(u);
Serial.print("i=");
Serial.println(i);
Serial.print("Pmot=");
Serial.println(Mes_Wmot);
*/
//
//correcteur
Ek = Cons_Wmot - Mes_Wmot; //calcul Erreur en puissance (consigne - mesure)
Uk = 0.02737806 * Ek - 0.021615667 * Ekm1 - 0.0017801932 * Ekm2 + 1.973477 * Ukm1 - 0.9734774 * Ukm2; //Equ de recurrence (moteur 250W - Test 2)
//Uk = 9.2067 * Ek - 15.012 * Ekm1 + 5.9004 * Ekm2 + 1.739 * Ukm1 - 0.73903 * Ukm2; //Equ de recurrence (moteur 350W - Test 1)
//Uk = 0.05193636164421996*Ek - 0.0289217814133178*Ekm1 - 0.007184380500059863*Ekm2 + 1.917763790949064*Ukm1 - 0.9177637909490634*Ukm2; //Equ de recurrence (moteur 250W - Test 1)
//Uk est la consigne en pas CNA (duty PWM de 0 a 255)
//application nouvelle consigne + bornage
if (Cons_Wmot == 0) Uk = 0; //RAZ pour correction BUG >>> VOIR AVEC JOCELYN
val1 = (int)Uk;
if (val1 > 153) // "153 + 51" car la tension maximale est de 4V sur le controleur brushless************/
{
val1 = 153;
}
if (val1 < 0)
{
val1 = 0;
//Uk = 0; //RAZ pour correction BUG >>> VOIR AVEC JOCELYN
}
//application sur controleur brushless
analogWrite(MotPin, (val1 + 51)); // "51" car la tension minimale est de 1V sur le controleur brushless
//backup
Ukm2 = Ukm1;
Ukm1 = Uk;
Ekm2 = Ekm1;
Ekm1 = Ek;
//
//affichage sur console DEBUG
/*
Serial.print(Cons_Wmot);
Serial.print(",");
Serial.print(Uk);
Serial.print(",");
Serial.print(val1);
Serial.print(",");
Serial.print(Mes_Wmot);
Serial.print(",");
Serial.println(Ek);
*/
//digitalWrite(OutTest, LOW);
interrupts();
}
/*******************************************************************************************/
//Gestion communication IHM <> Superviseur
// Stratgie de communication:
// 1. La tablette envoi priodiquement un ordre "MAJ+crc" de mise jour
// 2. Le superviseur vrifie toutes les " X " ms si un ordre est arriv
// 3. Si oui, le superviseur transmet la trame "IHM..."
// 4. Si non, on ne fait rien
void gestion_BT(void) {
char BTdata[] = {
'I', 'H', 'M', 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30 , 0x30 , 0x30, 0
}; //trame a envoyer
char RXbuffer[10], buffer[5], a, b, nbrx;
unsigned char crc, vit;
unsigned long v;
static unsigned char cnt_cnx = 0; //compteur temps de connexion pour gestion erreur 6 (gestion_BT appele tts les 50ms)
int w, c;
crc = 0;
if (++cnt_cnx >= 250) cnt_cnx = 250;
nbrx = IHMSerial.available(); //ordre recu ??
if (nbrx > 0) {
noInterrupts();
for (b = 0; b < nbrx; b++) {
RXbuffer[b] = IHMSerial.read(); //reception ordre
}
//validit ordre
if ((RXbuffer[0] == 'M') && (RXbuffer[2] == 'J')) {
//APPLI pour dbugage ********************************************************************
switch (RXbuffer[3])
{
case 'O':
LevelAssist = ASSIST_0;
BTdata[3] = 'O';
break;
case 'L':
LevelAssist = ASSIST_L;
BTdata[3] = 'L';
break;
case 'M':
LevelAssist = ASSIST_M;
BTdata[3] = 'M';
break;
default:
LevelAssist = ASSIST_L;
BTdata[3] = 'L';
break;
}
gestion_LEDMode(LevelAssist); //maj affichage
//
sprintf(buffer, "%03d", Vbatt);
for (a = 4; a <= 6; a++)
{
BTdata[a] = buffer[(a - 4)];
}
//
sprintf(buffer, "%03d", AffVitVelo);
for (a = 7; a <= 9; a++)
{
BTdata[a] = buffer[(a - 7)];
}
//
if (Tbatt > 99) Tbatt = 99; //bornage
sprintf(buffer, "%02d", Tbatt);
for (a = 10; a <= 11; a++)
{
BTdata[a] = buffer[(a - 10)];
}
//
w = (int)AffMesWmot; // Cons_Wmot ou Mes_Wmot mais moins stable (a voir...)
if (w > 999) w = 999; //bornage
sprintf(buffer, "%03d", w);
for (a = 12; a <= 14; a++)
{
BTdata[a] = buffer[(a - 12)];
}
//
BTdata[15] = erreur + 1; //offset pour eviter erreur =0
//
for (a = 0; a <= 15; a++) {
crc += BTdata[a];
}
BTdata[16] = crc;
//
//envoi
IHMSerial.println(BTdata);
//debug
//sprintf(buffer, "%03d", crc);
//Serial.println(buffer);
//sprintf(buffer, "%03d", nbrx);
//Serial.println(buffer);
//Serial.println(BTdata);
cnt_cnx = 0;
interrupts();
}
}
//Test absence/perte de connexion avec tlphone
if (cnt_cnx <= 200) {
bitClear(erreur, 6); //liaison Bluetooth OK
} else {
bitSet(erreur, 6); //Pas de reception d'ordre
}
}
/*******************************************************************************************/
//Gestion des LEDS Niveau d'assistance
void gestion_LEDMode(int v) {
switch (v) {
case ASSIST_0:
digitalWrite(LEDLEVEL_L, LOW);
digitalWrite(LEDLEVEL_M, LOW);
break;
case ASSIST_L:
digitalWrite(LEDLEVEL_L, HIGH);
digitalWrite(LEDLEVEL_M, LOW);
break;
case ASSIST_M:
digitalWrite(LEDLEVEL_L, HIGH);
digitalWrite(LEDLEVEL_M, HIGH);
break;
default:
digitalWrite(LEDLEVEL_L, LOW);
digitalWrite(LEDLEVEL_M, LOW);
break;
}
}
/*******************************************************************************************/
//Gestion des LEDS RGB statut de batterie
void gestion_LEDbatt(int v) {
if ((v < 145) || (v > 892)) { //Pb batterie ALLUMAGE BLEU
digitalWrite(LEDBAT_R, HIGH);
digitalWrite(LEDBAT_G, HIGH);
analogWrite(LEDBAT_B, 150);
} else if (v < 370) { // 0 30% ALLUMAGE ROUGE
analogWrite(LEDBAT_R, 150);
digitalWrite(LEDBAT_G, HIGH);
digitalWrite(LEDBAT_B, HIGH);
} else if (v < 610) { // 30 60% ALLUMAGE ORANGE
analogWrite(LEDBAT_R, 150);
analogWrite(LEDBAT_G, 245);
digitalWrite(LEDBAT_B, HIGH);
} else { // 60 100% ALLUMAGE VERT
digitalWrite(LEDBAT_R, HIGH);
analogWrite(LEDBAT_G, 170);
digitalWrite(LEDBAT_B, HIGH);
}
}
/*******************************************************************************************/
//Gestion des erreurs systme
// =0 si pas d'erreur majeure, =1 si pb
/*** DETAIL DE LA VARIABLE ERREUR ***/
//bit 0=1 si pas de pedalage,
//bit1=1 si ...,
//bit2=1 si ...,
//bit3=1 si ...,
//bit4=1 si pb batterie principale,
//bit5=1 si ...,
//bit6=1 si Pb communication Bluetooth
//bit7=1 si Pb temperature Pack batterie
/***/
unsigned char gestion_erreur(void) {
char a;
static boolean cl;
//ARRET VELO SI ERREUR MAJEURE (BATTERIE VIDE // TEMPERATURE PACK BATTERIE
a = erreur & 0b10010000; //on isole les erreurs mineures
if (a) {
//animation stripLED
cl = !cl;
if (cl == true) {
digitalWrite(LEDALERT, HIGH);
} else {
digitalWrite(LEDALERT, LOW);
}
return 1;
} else {
digitalWrite(LEDALERT, LOW);
return 0;
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Routine de lecture Temperature Interieure (CTN 10K)
float Thermistor(int RawADC) {
long Resistance;
float Temp; // Dual-Purpose variable to save space.
Resistance = 10000 * ((1024.0 / RawADC) - 1); //recup valeur CTN en ohms selon mesure ADC
Temp = log(Resistance / 10000.0); // ln(RT/R25)
Temp = 1 / (0.0033540164 + (0.000256985 * Temp) + (0.000002620131 * Temp * Temp) + (0.00000006383091 * Temp * Temp * Temp));
Temp = Temp - 273.15; // Convert Kelvin to Celsius
return Temp; // Return the Temperature
}
Comments