Bonjour,
J’essaie de faire un semoir qui sera monté sur une planteuse à patates. Il est entraîné par un moteur pas à pas.
Pour le pas à pas j’ai choisi la librairie (FastAccelStepper) qui tourne sur le coeur0 de l’ESP32, comme ça, le programme principal sur le coeur1 n’influence pas le Stepper.
Le problème vient quand j’envoie des informations sur le moniteur série, le pas à pas perd beaucoup de pas. Il fait des accoups et tourne anormalement lentement.
De ce que j’ai lu, l’ESP32 gère tous ce qui est communications sur le coeur0.
-
Donc est-ce-que je peux déplacer la gestion du port-série sur le coeur1 ?
-
Comment contrôler qu’elle cœur gère le port-série ?
Pour info: Avec le port-série au minimum, actuellement en fonctionnement, l'ESP fait ~60 x la loop() par milli-seconde.
Si ça peux aider, voilà le code actuel. Mais je vous préviens c’est en chantier et c’est un truc de novice.
//forum : https://forum.arduino.cc/c/international/francais
//Pointeur vers RangMachine, voir: https://forum.arduino.cc/t/verifier-si-une-instance-de-bibliotheque-est-declaree/1117499/27
//Fonction avec argument(s) optioneel voir: https://forum.arduino.cc/t/fonction-avec-argument-optionnel-qui-compile-pas/1117046
//Connection du codeur voir: https://forum.arduino.cc/t/codeur-npn-5v-24v-sur-esps32-3-3v/1118626
#define version V0_4_02
// Description:
//
//Archithecture:
//Micro-contrôleur: ESP32_38pins
//Codeur: 600points/tour >> informe de la distance parcourue par la roue de la machine
//Pas-à-pas Nena../200step/tour >> entraine la roue doseuse du semoire
//Driver A4988 >> pilotage du moteur pas-à-pas. (avec ESP32, voir: https://www.youtube.com/watch?v=6rjTFtLgqZU)
//Boost-voltage 12-24V (optionnel) >> sert à transformer le ~12v du véhicule en 24v pour le moteur, plus grand régime avec 24v qu'avec les ~13,5v du véhicule)
//Pour chaque rang de la planteuse
//Un capteur de passage de plant >> sert à détecter si un plant à réellement été planté. (pour les pattates, j'utilise un switch sur la chaîne d'allimentation)
//Led témions-manque LED5mm_Rouge >> indicateur lumineux servent à avertire de chaque plant non détecté par le capteur de passage ou la mise en alarme du rang
//>>Pas encors paramètré<< //Led rang-actif LED3mm_verte >> indique si le rang de la planteuse est activé
//Les autres switchs (interrupteurs)
//[swSemeOn] >> active le semoire
//[swPlanteOn] >> active les rang de la planteuse
//[swMoteurOn] >> activation mannuel du moteur du semoire (pour purger le mécanisme, par exemple)
//[swAlReset] >> effacer les alarmes et réinitaliser les paramètres d'alarme après résolution du problème (les anciennes valeurs seront conservées pour les statistiques finals mais plus utilisées pour les alarmes)
// swBuzzerOff >> pour éteindre l'alarme sonor. (Brancher directement sur le câble d'allimentation du buzzer ou sur son relais)
//Les autres témoins
//Lampe Alarme central >> Relais activant un témions lumineux d'alarme centralisée
//Buzzer Alarme central >> Relais activant un témoins sonor d'alarme centralisée
//LedSemOn LED5mm_Vert >> allumée lorce-que le semoire est actif
//LedPlanteON LED5mm_vert >> allumée si tous les rang de la planteuse sont actif, clignotte si les rang sont partiellement actif.
//Modifications:
//V0_3_0 et V0_3_01
//-mise à jour de la position current du stepper à 2'146'000'111
//-lors de la mise à jour avec [setCurrentPosition()] ou [addCurrentPosition()], [getCurrentPosition()] prend un certin temps à ce stabiliser.
// ce temps de stabilisation fait perdre quelques pas au moteur. donc ma solution est de le faire le moins souvent possible
// je le fait que quand le compteur dépasse 2 milliard de stepp (ou nStepperTour dépasse 60'000).
//-correction de l'addition des stepps pour le calcul de la vitesse
//-correction du calcul de vitesse (ajout de la ligne :TempVtI ++;)pour tenir compte du dernier enregistrement
// [#define DEBUGcalculSpeed] pour vérifier le calcul de la vitesse
//-déplacement des Pins du codeur (à 0 et 2 celà empèche le téléverssement; déplacer au 26 et 27)
//-ajout variable nStepperTour: éviter que le moteur s'embale à cause d'une décélération trop lente
//-avec l'ancienne version, le moteur s'embalait lors d'arrêt brusque, il décélairait pas asseé vite et recommancait une nouvelle boucle ect...ect...
//-avec l'ajout de [nStepperTour] le retard/avance du moteur est calculé sur beaucoup-plus de tours.
//-amélioration du calcul de retard (lissage) à l'aide du traceur série ([#define DEBUGstepperValTraceur])
//V0_3_02
// mise à jours des variables de vitesse
// ajout des fonctios de vitesse
// ajout des fonctions de distance
// changement du calcul de vitesse du stepper (sans pris en charge de la vitesse d'avancement, "plus réactif")
// ALARME SUR-VITESSE : ajout d'une alarme de vitesse limite du stepper (rpm trop rapide)
// ajout lampe alarme centrale sur Pin 25
// remplacer [vtSteppSec] Par [vtSteppMin]
// ajout switch on-off plante et on-off seme >>[swPlanteOn] et [swSemeOn]
// Mise en place de la bibliothèque [rangMachine]
//V0_3_03
// transformer les rangMachine en tableau de pointeurs autoévolutif celon le nombre de rangs
//paramètrer le logitiel à la bibliothèque [rangMachine]
// corriger la fonction [majAlarme()]
// intégrer le buzzer à l'alarme central [majAlarme()]
// paramètrer switch on-off plante et on-off seme >>[swPlanteOn] et [swSemeOn]
// ajouter un switch purger [swMoteurOn] pour purger manuellement le semoir avant l'étalonage. (aussi utile pour un contrôle visuel de fonctionnement du semoir)
//V0_4_01
// refaire le Debouns switch dans [rangMachine::addPoints()] est réécriture des déclancheurs, ajout moyenne majEspacePlants
//>>> A FAIRE:
// terminer la bibliothèque [rangMachine]
// nettoyer la bibliothèque [rangMachine]
// faire les fonctions de statistiques de la planteuse (partielement fais)
// faire les fonctions de statistiques du semoire
// ajout distance semée (différant de distance plantée)>> [cptPntDistSeme] / [cptPntDistPlante] /global [cptPntDist]
// contrôler les calcules de vitesses, la vitesse du PàP me semble incoérante
// Ajouter un capteur de hall sur le rouleau pour contrôler le blocage du semoir et faire les fonctions en découlant
// A tester: Envoyer les changements de vitesse au stepper au minimum toutes les 2millis()
// A tester: Déplacer le "Serial.beguine" sur le coeur1
//FIN modif
#include <Arduino.h>
#include <FastAccelStepper.h>
FastAccelStepperEngine engine = FastAccelStepperEngine();
FastAccelStepper *stepper;
#include "rangMachine.h"
const uint8_t nbrlignePlanteuse = 2; // nombre de lignes de la planteuse >> actuellement maximum 4 lignes
//LES PINS
//codeur
const uint8_t codeurAPin = 14;//27;
const uint8_t codeurBPin = 27;//14;
//stepper
#define stepPinStepper 16
#define enablePinStepper 17
#define dirPinStepper 4
//rang planteuse (switch et led manque un plant)
const uint8_t rangPinSwitch[4]{23, 21, 18, 2};
const uint8_t rangPinLedManque[4]{22, 19, 5, 15};
//Old variante: rangMachine rang1(23,22);
//rangMachine rang2(21,19);
//rangMachine rang3(18,5);
//rangMachine rang4(2,15);
//switchs
const uint8_t swSemeOn = 36;//35;
const uint8_t swPlanteOn = 39;//32;
const uint8_t swAlReset = 35;//25;
const uint8_t swMoteurOn = 34;//33;
// swBuzzerOff >> Brancher directement sur le câble d'allimentation du buzzer ou sur son relais
//témoins
//const uint8_t ledStepper = 18; >> branchée sur enablePinStepper et VC
const uint8_t ledAlCentral = 32;
const uint8_t buzzAlCentral = 33;
const uint8_t ledSemeOn = 26;
const uint8_t ledPlanteOn = 25;
//FIN des pins
//#define DEBUG
#ifdef DEBUG
//#define DEBUGloopStepp_stepp
#define DEBUGloopSpeed //V0.3.4 Environ de 60'400 loop/s; V0.4.0(2rangs) ~59'000 loop/s
//#define DEBUGAlarme
//#define DEBUGswitch
//#define DEBUGcodeur
//#define DEBUGcodeurSpeed
//#define DEBUGcalculSpeed
//#define DEBUGstepper
//#define DEBUGenableOutputs
//#define DEBUGstepperValeurs
//#define DEBUGstepperValTraceur //comme [DEBUGstepperValeurs] mais sur le traceur série
//#define DEBUGstepperSpeed
//#define DEBUGmanques
#endif
#ifdef DEBUGloopSpeed
uint16_t DebugCptLoop = 1;
uint16_t DebugCptLoopMultiple = 1;
uint32_t DebugTimmerLoop = millis();
#endif
#ifdef DEBUGAlarme
byte DebugAlarme1 = 99;
uint8_t DebugAlOld_cptManqueRapide = 0;
uint32_t DebugAlOld_cptManque = 0;
uint64_t DebugAlOld_cptPlant = 0;
#endif
//FIN debug
#define InfoSerialMoniteur //Afficher les information importante du déroulement du programmme sur le moniteur série
//LES VARIABLES :
//Variables Etalonnage
const uint16_t steppTour = 2000; //nombre de pas pour un tour machine (peut-hêtre varier pour modifier la precision de l'étalonnage. Ici = 10 tours du moteur pas-à-pas.)
const uint16_t pntSteppTour = 12000; //nombre de points de codeur pour un tour machine (1[steppTour]).
const uint32_t pnt100m = 100000; //nombre de points du codeur pour une distance de 100 mètres.
const int8_t valeurPnt = -1; //valeur d'un point; 1 = horaire; -1 = anti-horaire
const uint16_t timelapseVt = 16; //temps entre deux mesure de vitesse (ne pas déssendre en dessous de 10 pour une vitesse stable)
//Varible Planteuse
rangMachine* lignePlanteuse[nbrlignePlanteuse];
const uint16_t distancePlant = 570; // distance en points entre chaque plants
//const uint16_t debouncePlante = distancePlant/3; // distance de passage d'un plant sous le switch (1pnt ~ 1mm d'avancement de la planteuse)
byte valRangAlarme[nbrlignePlanteuse];
byte oldValRangAlarme[nbrlignePlanteuse];
//Variables points et stepps
int16_t codeurPnt = 0 ; //nombre de points enregistrés par le codeur pas encors traités dans la boucle
int16_t newPnt = 0; //nombre de points traités par la boucle en cour d'exécution.
int16_t newPntStepper = 0; // nombre de points pour le semoir
int32_t lastPntPos = 0; //position du codeur (tour machine) lors de la boucle précédante.
int32_t lastSteppPos = 0; //position du stepper (tour machine) lors de la boucle précédante.
uint16_t nStepperTour = 0; //nombre de fois [steppTour] à enlever à [stepper->getCurrentPosition] pour avoir ça position "angulaire"
int16_t newStepp = 0; //nombre de pas à ajouter pour la boucle en cour d'exécution.
uint16_t cptPntVt = 0; //nombre absolut de points à ajouter pour le calcul de la vitesse { += abs(newPnt)}.
int32_t cptPntDist = 0; //nombre de points du compteur de distance parcourue. Compteur vidé tous les kilo-mètres dans [cptPntKm].
int16_t cptPntKm = 0; //nombre de kilomètres parcourus par la machine.
int32_t cptPntDistSeme = 0; //nombre de points du compteur de distance parcourue. Compteur vidé tous les kilo-mètres dans [cptPntKmSeme].
int16_t cptPntKmSeme = 0; //nombre de kilomètres parcourus par la machine.
int32_t cptPntDistPlante = 0; //nombre de points du compteur de distance parcourue. Compteur vidé tous les kilo-mètres dans [cptPntKmPlante].
int16_t cptPntKmPlante = 0; //nombre de kilomètres parcourus par la machine.
//Variables temps et vitesses
uint32_t lastTime = millis(); //milliseconde de référence lors de la boucle précédante.
uint32_t newTime = lastTime; //milliseconde de référence lors de la boucle en cour d'exécution.
uint32_t newTimelapseVt = millis() + timelapseVt; //délais pour la prochaine mesure de vitesse += [timelapseVt]
uint16_t tblPntVt[21]; // tableau pour le stockage du nombre de points vitesse mesurés. (Utilisé pour lissage de la vitesse mesurée).
int8_t iTblPntVt = -20; //position de la case du tableau en cour d'écriture.
bool jTblPntVt = true; //première ou deusième mesure de vitesse pour moyenner la case en cour d'écriture. (chaque case du tableau contient les somme des deuxdirnière mesures, sauf au démarrage, il y a une mesure fois deux dans chaque case pour gagner en vitesse de mise à jour)
uint32_t vtPntMin; //vitesse d'avancement en points/minutte.
int32_t vtSteppMin; //vitesse moteur en stepp/minutte
float vtMsec; //vitesse d'avancement en mètres/seconde
//Avertissement et communications: ->lampes témoins; signal sonore; communication avec le boitier de commande; communication avec le GPS; ...
//Variables alarmes
uint32_t lastTimeAlBlink = millis(); //dernière fois que la lampe alarme centrale à été allumée
uint32_t lastTimeAlBuzz = millis();
int8_t etatAlLampe = LOW; // état de la lampe alarme centrale >> 0 = éteinte; 1 = allumée
int8_t etatAlBuzz = LOW;
byte alarme1 = 0; //bit0 = alarmeOn;
byte oldAlarme1 = 0;//bit1 = alarme ligne 1;
//bit2 = alarme ligne 2;
//bit3 = alarme ligne 3;
//bit4 = alarme ligne 4;
//bit5 = PàP trop vite;
//bit6 = PàP bloqué;
//bit7 = buzzerOn;
//bit à bit Voir: https://www.locoduino.org/spip.php?article70
////bitWrite(x, n, b) permet d’écrire un bit. Le premier argument, x est la donnée où on écrit le bit, le second argument, n est le numéro du bit et le 3e, b est la valeur à écrire, 0 ou 1.
//bitRead(x, n) permet de lire un bit. Le premier argument, x est la donnée d’où on lit le bit, le second argument, n est le numéro du bit.
//bitSet(x, n) permet de mettre à 1 un bit. Le premier argument, x est la donnée où on écrit le bit, le second argument, n est le numéro du bit
//bitClear(x, n) permet de mettre à 0 un bit. Le premier argument, x est la donnée où on écrit le bit, le second argument, n est le numéro du bit
//Autres variables
//Switch pilotage
bool swSeme = false;// = digitalRead(swSemeOn);
bool swPlante = false;// = digitalRead(swPlanteOn);
uint32_t swSemPlanDebounce = 0;
//bool alReset = false;
//bool saveSD = false;
//Compteurs de manques: -> contrôle si un planton déclanche le switch tous les x centimètres sur chaque ligne de la planteuse
//>>> Remplacer par la bibliothèque [rangMachine]
//Variables Stepper
int16_t miniSteppSpeed = 5;
int16_t maxiSteppSpeed = 1333; //1667 = 500RPM; 1500 = 450RPM; 1333 = 400RPM; ...
int32_t newSpeedStepp = 0;
int32_t retardStepp = 0;
int32_t lastRetardStepp = 0;
int32_t majSpeedStepp = 0;
bool stepperOn = false;
// //Ancienne version: int8_t iMajStepperCurrentPos = 0; //compteur pour éviter la re-mise-à-jour du compteur de position du PàP avant son activation complette
//FIN des variables
void manuelMoteurOn(uint16_t ManuelOnSpeed = 100); //Voir: https://forum.arduino.cc/t/fonction-avec-argument-optionnel-qui-compile-pas/1117046/5
void setup() {
//#if (defined DEBUG || defined InfoSerialMoniteur)
Serial.begin(115200);
delay (5);
#ifdef DEBUG
Serial.println("\t\t S T A R T (setup)");
#endif
//#endif//DEBUG
//Pins Mode
pinMode(codeurAPin, INPUT_PULLUP);
pinMode(codeurBPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(codeurAPin), comptePnt, RISING); //RISING ; CHANGE);
pinMode(swSemeOn, INPUT); // pull-up externe >>INPUT_PULLUP);
pinMode(swPlanteOn, INPUT); // pull-up externe >>INPUT_PULLUP);
pinMode(swAlReset, INPUT); // pull-up externe >>INPUT_PULLUP);
pinMode(swMoteurOn, INPUT); // pull-up externe >>INPUT_PULLUP);
pinMode(ledAlCentral, OUTPUT);
pinMode(buzzAlCentral, OUTPUT);
pinMode(ledSemeOn, OUTPUT);
pinMode(ledPlanteOn, OUTPUT);
//Initialiser les rang
memset(lignePlanteuse, 0, sizeof lignePlanteuse); //=> Initialise les pointeurs créés ci-dessus à NULL
memset(valRangAlarme, 0, sizeof valRangAlarme);
memset(oldValRangAlarme, 0, sizeof oldValRangAlarme);
for (uint8_t i = 0; i < nbrlignePlanteuse; i++) {
lignePlanteuse[i] = new rangMachine (rangPinSwitch[i], rangPinLedManque[i]);
}
//Initialiser le Pas_à_pas
engine.init();
stepper = engine.stepperConnectToPin(stepPinStepper); // ### ESP32 * allows up to 200000 generated steps per second
if (stepper) {
stepper->setDirectionPin(dirPinStepper);
stepper->setEnablePin(enablePinStepper);
stepper->setSpeedInHz(10);
stepper->setAcceleration(6000); //steps/s²
stepper->setCurrentPosition(0);
stepper->setAutoEnable(true); //void setAutoEnable(bool auto_enable);
stepper->setDelayToEnable(60); //int8_t setDelayToEnable(uint32_t delay_us);
stepper->setDelayToDisable(1500); //void setDelayToDisable(uint16_t delay_ms);
if (stepper->getCurrentPosition() >= steppTour) {
nStepperTour = int(stepper->getCurrentPosition() / steppTour);
}
}
digitalWrite(ledAlCentral, etatAlLampe);
#ifdef InfoSerialMoniteur
Serial.println ("Informations sur le moniteur série activées");
#endif
#ifdef DEBUG
Serial.println ("Mode DEBUG activé");
#endif
#if (defined DEBUG || defined InfoSerialMoniteur)
Serial.println("*********************************************************END SETUP***");
#endif//DEBUG
delay(5);
}
void loop() {
//Initialise les varibles traitées pou cette boucle
#ifdef DEBUGloopStepp_stepp
Serial.print("DEBUGloopStepp_stepp: A01, ");
#endif//DEBUG
newPnt = codeurPnt;
newTime = millis();
//Contrôle les switchs
#ifdef DEBUGloopStepp_stepp
Serial.print("02, "); //A_02
#endif//DEBUG
if(swSemPlanDebounce < millis()){
if(!swSeme != digitalRead(swSemeOn)){
swSeme = digitalRead(swSemeOn); swSeme = !swSeme;
swSemPlanDebounce = millis()+20;
Serial.println("\nSeme switch changé");
#ifdef DEBUGswitch
if(swSeme) Serial.println("Seme ON"); else Serial.println("Seme OFF");
#endif
}
if(!swPlante != digitalRead(swPlanteOn)){
swPlante = digitalRead(swPlanteOn); swPlante = !swPlante;
swSemPlanDebounce = millis()+20;
#ifdef DEBUGswitch
if(swPlante) Serial.println("Plante ON"); else Serial.println("Plante OFF");
#endif
}
}
#ifdef DEBUGloopStepp_stepp
Serial.print("03, ");
#endif//DEBUG
if (!digitalRead(swAlReset)) alarmeReset();
#ifdef DEBUGloopStepp_stepp
Serial.print("04, ");
#endif//DEBUG
if (!digitalRead(swMoteurOn)) manuelMoteurOn();
//Calcul de la distance et vitesse d'avancement
#ifdef DEBUGloopStepp_stepp
Serial.print("| C01, ");
#endif//DEBUG
if (newPnt != 0) {
addDistance();
}
else newPntStepper = 0;
cptPntVt += abs(newPnt);
if (newTimelapseVt <= newTime) {
addVt();
newTimelapseVt += timelapseVt;
#ifdef DEBUGstepperValTraceur
Serial.print(""); Serial.print(retardStepp);
Serial.print(" , "); Serial.print(majSpeedStepp);
Serial.print(" , "); Serial.print(newSpeedStepp);
Serial.print(" , "); Serial.println(vtSteppMin/60);
#endif
}
//Convetie les points en stepp >> newStepp = nombre de points à ajouter au moteur
#ifdef DEBUGloopStepp_stepp
Serial.print("| B01, ");
#endif//DEBUG
newStepp = ((lastPntPos + newPntStepper) * steppTour / pntSteppTour) - lastSteppPos;
if(newStepp < 1) { //éviter au moteur de tourner en arrière
newStepp = 0;
}
//Evoye les points aux rangs et contrôle les alarmes manques
#ifdef DEBUGloopStepp_stepp
Serial.print("| D01, ");
#endif//DEBUG
for(int i = 0; i < nbrlignePlanteuse; i ++){
valRangAlarme[i] = lignePlanteuse[i]->addPoints(newPnt, true); //.addPoints(nombre_points_a_ajouter, rang_activé) retourne: byte rang_Alarmes (voir bibliothèque pour détails)
if(valRangAlarme[i] > 1) {bitSet(alarme1, i+1);}
else if(valRangAlarme[i] == 1) { }
else {bitClear(alarme1, i+1);}
}
//Controle le retard et adapte la vitesse du moteur
#ifdef DEBUGloopStepp_stepp
Serial.print("| E01, ");
#endif//DEBUG
int32_t TempStepperAngle = stepper->getCurrentPosition() - nStepperTour * steppTour;
retardStepp = (lastSteppPos + newStepp) - TempStepperAngle;
int32_t reelSpeedMoteur = 0;
if(swSeme) {
reelSpeedMoteur = stepper->getCurrentSpeedInMilliHz()/1000;
}
majSpeedStepp = (retardStepp + (abs(reelSpeedMoteur) +1)/10) * 5; // [x10] pour compensser dans le 10èmme de seconde // [-vtSteppMin/60 / Y] pour avoir un temp de décélération
newSpeedStepp = (majSpeedStepp);
if (newSpeedStepp < miniSteppSpeed) {newSpeedStepp = 0;}
else if (newSpeedStepp > maxiSteppSpeed) {newSpeedStepp = maxiSteppSpeed;}
else if (reelSpeedMoteur > 1500) {stepper->setAcceleration(2000);}
else if (reelSpeedMoteur < 1400 && reelSpeedMoteur > 1100) {stepper->setAcceleration(5000);}
else {stepper->setAcceleration(10000);}
// //Test vélossité : vitesse envoyé - vitesse réelle >>> voir version 0_3_02
#ifdef DEBUGstepperSpeed
//Serial.print("points de retard "); Serial.print(retardStepp);
//Serial.print("\tpoints logitiel "); Serial.print(lastSteppPos);
//Serial.print("\tpoints moteur "); Serial.print(stepper->getCurrentPosition());
//Serial.print("\tmise à jour vitesse "); Serial.print(majSpeedStepp);
Serial.print("\tvitesse calculcodeur ");
Serial.print(vtSteppMin/60);
Serial.print("\tvitesse points/s ");
Serial.print(vtPntMin/60);
#endif
//envoye la nouvelle vitesse au moteur //>> newSpeedStepp = vitesse à envoyer au moteur
#ifdef DEBUGloopStepp_stepp
Serial.print("| F01, ");
#endif//DEBUG
stepperOn = stepper->isRunning(); //Renvoye vrai pendant l'arrêt du moteur (décélération jusqu'au stop)
if (newSpeedStepp != 0) {
stepper->setSpeedInHz(newSpeedStepp);
if (!stepperOn) {
stepper->runForward();
}
else {
stepper->applySpeedAcceleration();
}
//stepper->move(newStepp); //le PaP est régulé uniquement par la vitesse. (le nombre de pas influence la vitesse par l'intermédiaire du [retardStepp])
#ifdef DEBUGstepperSpeed
Serial.print(" | newSpeedStepp\t");
Serial.print(newSpeedStepp);
#endif
}
else {
if (stepperOn) {
stepper->applySpeedAcceleration(); //Pour appliquer la valeur de décélération pendant l'arrêt du moteur
stepper->stopMove();
#ifdef DEBUGstepperSpeed
Serial.print("\tArrêt du moteur envoyé");
#endif
}
else {
//else if (stepper->isEnableStepper()) { //Trouver la fonction qui renvoie l'état de la pin enable du moteur !! getEnablePinHighActive()ne fonctionne pas
#ifdef DEBUGstepperSpeed
Serial.print("\tMoteur est à l'arrêt et il est désactivé");
#endif
if (stepper->getCurrentPosition() > 2000111222){ // ~ 147'000'000 de stepp avant le bouclage automatique du comteur [int32_t]
majStepperCurrentPos(); //profiter de l'arrêt du PàP pour remettre "à zéro" son compteur de position
}
else if (nStepperTour > 55000) {
majStepperCurrentPos(); //profiter de l'arrêt du PàP pour remettre "à zéro" son compteur de position
}
}
#ifdef DEBUGstepperSpeed
Serial.print("\tnewSpeedStepp :\t");
Serial.print(newSpeedStepp);
#endif
}
#ifdef DEBUGstepperSpeed
Serial.println();
#endif
#ifdef DEBUGenableOutputs
//Serial.println(stepper->enableOutputs());
//Serial.println(stepper->disableOutputs());
#endif
#ifdef DEBUGstepperValeurs
Serial.print("> isRunning "); Serial.print(stepper->isRunning());
Serial.print("\tisStopping "); Serial.print(stepper->isStopping());
//Serial.print("\t||\tretard "); Serial.print(stepper->disableOutputs());//>>Modifie la valeur Enable à false //bool disableOutputs();returns true, if disabled
//Serial.print("\tenableOutputs "); Serial.print(stepper->enableOutputs());//>>Modifie la valeur Enable à true //bool enableOutputs();returns true, if enabled
Serial.print("\t||\tretard "); Serial.print(retardStepp);
Serial.print("\tmajSpeedStepp "); Serial.print(majSpeedStepp);
Serial.print("\tnewSpeedStepp "); Serial.print(newSpeedStepp);
Serial.print("\tvtSteppSec "); Serial.print(vtSteppMin/60);
Serial.print("\tvtPntMin "); Serial.print(vtPntMin);
Serial.print("\tgetSpeedInHz "); Serial.print(stepper->getSpeedInMilliHz()/1000);//uint32_t getSpeedInMilliHz()
//Serial.print("\txxx "); Serial.print(xxx);
#endif
//Contrôle du steppermotor
#ifdef DEBUGloopStepp_stepp
Serial.print("| G01, ");
#endif//DEBUG
if (stepperOn){
if (newSpeedStepp >= maxiSteppSpeed || vtSteppMin/60 > maxiSteppSpeed *18/20){
bitSet(alarme1, 5); //Alarme On
}
else if (bitRead(alarme1, 5)){
if (newSpeedStepp < maxiSteppSpeed *19/20 && vtSteppMin/60 < maxiSteppSpeed *26/30){
bitClear(alarme1, 5); //AlarmeOff
}
}
}
//Réinitialisation des variables
#ifdef DEBUGloopStepp_stepp
Serial.print("| H01, ");
#endif//DEBUG
lastTime = newTime;
codeurPnt -= newPnt;
lastPntPos += newPntStepper;
lastSteppPos += newStepp;
if (lastPntPos >= pntSteppTour) {
lastPntPos -= pntSteppTour;
lastSteppPos -= steppTour;
nStepperTour ++;
//Si le compteur arrive à ça limite, vidange des compteurs. (normalement se fait avant d'arriver à ce stade de remplissage, quand le moteur est à l'arrêt)
if (stepper->getCurrentPosition() > 2146000123 || nStepperTour > 64000) {
majStepperCurrentPos();
}
}
lastRetardStepp = retardStepp;
if (alarme1 != 0) majAlarme(); //ATTEENTION, c'est majAlarme qui doit metre le 1er bit à zéro pour permettre l'extinction de l'alarme
//#ifdef DEBUG...
#ifdef DEBUGloopStepp_stepp
Serial.println("| I01, ");
#endif//DEBUG
#ifdef DEBUGloopSpeed
DebugCptLoop ++;
if(DebugCptLoop>10000){
Serial.print("*");
DebugCptLoop = 1;
DebugCptLoopMultiple ++;
if(DebugCptLoopMultiple>100){
DebugCptLoopMultiple = 1;
Serial.println( "1'000'000 de loop");
Serial.print(" (millis pour 1*10^6 loop = ");
Serial.print(millis()- DebugTimmerLoop);
Serial.print(" | loop/s = ");
Serial.print(1000000000 / (millis()- DebugTimmerLoop));
Serial.println(" )");
DebugTimmerLoop = millis();
}
}
#endif
#ifdef DEBUGAlarme
//Rang à analyser:
#define _TempRang 1
#ifdef _TempRang
if(lignePlanteuse[_TempRang] != NULL) {
if(lignePlanteuse[_TempRang]->getNbrPlanter() != DebugAlOld_cptPlant){
Serial.print("O");
DebugAlOld_cptPlant = lignePlanteuse[_TempRang]->getNbrPlanter();
}
//else if(lignePlanteuse[_TempRang]->getNbrManquer() != DebugAlOld_cptManque){
if(lignePlanteuse[_TempRang]->getNbrManquer() != DebugAlOld_cptManque){
Serial.print("X");
//testDEBUG: Serial.println(lignePlanteuse[_TempRang]->getNbrManquer()); delay(300);
DebugAlOld_cptManque = lignePlanteuse[_TempRang]->getNbrManquer();
}
//else {Serial.print(".");}
}
#endif
if (alarme1 != DebugAlarme1){
Serial.print ("byte alarme1 = "); Serial.print(alarme1);
if(bitRead(alarme1, 1)) Serial.print ("\t>> alarme ligne1");
if(bitRead(alarme1, 2)) Serial.print ("\t>> alarme ligne2");
if(bitRead(alarme1, 3)) Serial.print ("\t>> alarme ligne3");
if(bitRead(alarme1, 4)) Serial.print ("\t>> alarme ligne4");
if(bitRead(alarme1, 5)) Serial.print ("\t>> alarme trop vite");
if(bitRead(alarme1, 6)) Serial.print ("\t>> alarme semoir bloqué");
for(int i = 0; i < nbrlignePlanteuse; i ++){
if(bitRead(alarme1, i+1)){
byte _TempAlarmeRangByte = lignePlanteuse[i]->getAlarme();
Serial.print ("\n >>> byte alarme ligne "); Serial.print(i+1); Serial.print(" = "); Serial.print(_TempAlarmeRangByte);
if(bitRead(_TempAlarmeRangByte, 0)) Serial.print ("\t>> Manque un plant");
if(bitRead(_TempAlarmeRangByte, 1)) Serial.print ("\t>> alarme manques répétés");
if(bitRead(_TempAlarmeRangByte, 2)) Serial.print ("\t>> alarme % manque dépassé");
if(bitRead(_TempAlarmeRangByte, 3)) Serial.print ("\t>> alarme capteur bloqué à ON");
if(bitRead(_TempAlarmeRangByte, 4)) Serial.print ("\t>> alarme plants trop proche"); //Alarme pas encors programmée
if(bitRead(_TempAlarmeRangByte, 5)) Serial.print ("\t>> alarme bit5"); //Alarme pas utilisée
if(bitRead(_TempAlarmeRangByte, 6)) Serial.print ("\t>> alarme bit6"); //Alarme pas utilisée
if(bitRead(_TempAlarmeRangByte, 7)) Serial.print ("\t>> alarme bit7"); //Alarme pas utilisée
}
}
DebugAlarme1 = alarme1;
Serial.println();
}
#endif
#ifdef DEBUGstepperValeurs
Serial.println(" >> next loop >>");
#endif
#ifdef InfoSerialMoniteur
printInfoSerialMoniteur();
#endif
}
void majStepperCurrentPos(){
if (nStepperTour > 2){ //Contrôle si la mise à jour à u le temp de s'activer;
int32_t TempStepperPos = stepper->getCurrentPosition();
stepper->setCurrentPosition(TempStepperPos - nStepperTour * steppTour);
nStepperTour = 0;
#ifdef DEBUG
Serial.println("\n\n*****************************************************");
Serial.print("stepper->getCurrentPosition() :\t");
Serial.println(TempStepperPos);
Serial.println("\n\tMise à jour de la position de moteur pas à pas\n");
delay(5);
Serial.print("stepper->getCurrentPosition() :\t");
Serial.println(stepper->getCurrentPosition());
Serial.println("\n*****************************************************\n");
#endif
} else {
#ifdef DEBUG
Serial.println("\n\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
Serial.println("\tmaj ANNULEE de la position de moteur pas à pas\n");
Serial.print("stepper->getCurrentPosition() :\t");
Serial.println(stepper->getCurrentPosition());
Serial.println("\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
#endif
}
}
void addDistance(){
if (swSeme) newPntStepper = newPnt; else newPntStepper = 0;
if (newPnt < 0){
if (cptPntDist > newPnt * -1) {
cptPntDist += newPnt;
}
else if (cptPntKm > 0){
cptPntDist += pnt100m * 10;
cptPntKm --;
cptPntDist += newPnt;
}
else {cptPntDist = 0;}
if(swSeme){
if (cptPntDistSeme > newPnt * -1) {
cptPntDistSeme += newPnt;
}
else if (cptPntKmSeme > 0){
cptPntDistSeme += pnt100m * 10;
cptPntKmSeme --;
cptPntDistSeme += newPnt;
}
else {cptPntDistSeme = 0;}
}
else {cptPntDistSeme = 0;}
if(swPlante){
if (cptPntDistPlante > newPnt * -1) {
cptPntDistPlante += newPnt;
}
else if (cptPntKmPlante > 0){
cptPntDistPlante += pnt100m * 10;
cptPntKmPlante --;
cptPntDistPlante += newPnt;
}
else {cptPntDistPlante = 0;}
}
else {cptPntDistPlante = 0;}
}
else {
cptPntDist += newPnt; //nombre de points du compteur de distance parcourue. Compteur vidé tous les kilo-mètres dans [cptPntKm].
if(swSeme) cptPntDistSeme += newPnt;
if(swPlante) cptPntDistPlante += newPnt;
}
if (cptPntDist >= pnt100m * 10) {
cptPntKm ++; //nombre de kilomètres parcourus par la machine.
cptPntDist -= pnt100m * 10;
}
if (cptPntDistSeme >= pnt100m * 10) {
cptPntKmSeme ++; //nombre de kilomètres parcourus par la machine.
cptPntDistSeme -= pnt100m * 10;
}
if (cptPntDistPlante >= pnt100m * 10) {
cptPntKmPlante ++; //nombre de kilomètres parcourus par la machine.
cptPntDistPlante -= pnt100m * 10;
}
}
void addVt(){
int8_t TempVtI = 20;
int32_t TempVtSommePnt = 0;
if (iTblPntVt < 0){ //enregistrement simple au demarrage
TempVtI += iTblPntVt;
tblPntVt[TempVtI] = cptPntVt * 2;
iTblPntVt ++;
TempVtI ++;
jTblPntVt = true;
}
else { //Enregistrement double si différent de 0 points / seconde (pour faire désendre plus rapidement lors d'arrêt brusque)
//>> implique qu'il y est aumoins 1 point pendant timelapseVt[millis] pour la vitesse minimum
if (jTblPntVt) {
tblPntVt[iTblPntVt] = cptPntVt * 2;
if (cptPntVt == 0) {
iTblPntVt ++;
}
else {
jTblPntVt = false;
}
}
else {
// uint16_t TempTblVal = tblPntVt[iTblPntVt] / 2;
// tblPntVt[iTblPntVt] = TempTblVal + cptPntVt;
tblPntVt[iTblPntVt] = tblPntVt[iTblPntVt] / 2 + cptPntVt;
iTblPntVt ++;
jTblPntVt = true;
}
}
if (iTblPntVt > 19) {
iTblPntVt = 0;
}
//Calculs
for (int i=0; i<TempVtI; i++) {
TempVtSommePnt += tblPntVt[i];
}
vtPntMin = TempVtSommePnt * 60000 / timelapseVt / 40; //en [pnt/min] >> pnt = TempVtSommePnt >> temps[min] = 40[enregistrements] *timelapseVt[millis] /60'000 [millis/minutte]
vtSteppMin = vtPntMin * steppTour / pntSteppTour;
//vtMsec = int((TempVtSommePnt*10000*1000/timelapseVt/40)/pnt100m)/100;
//Test print Vitesse: printVtKmH(); Serial.print(" km/h\t");printVtMs(); Serial.print(" m/s\t");Serial.print(vtPntMin/60);Serial.print(" pnt/s\t|\t"); Serial.print(vtSteppMin/200); Serial.print(" RPM moteur\t"); printDistMpalnter(); Serial.println(" mètres plantés");
#ifdef DEBUGcalculSpeed
Serial.print("\niTblPntVt ");
Serial.print(iTblPntVt );
Serial.print("\tcptPntVt ");
Serial.print(cptPntVt);
Serial.print("\tvtSteppMin ");
Serial.print(vtSteppMin);
Serial.print("\tvtPntMin ");
Serial.print(vtPntMin);
Serial.print("\tvtkm/h "); printVtKmH();
Serial.print("\tTempVtSommePnt ");
Serial.println(TempVtSommePnt);
#endif
if (TempVtSommePnt == 0) {iTblPntVt = -20;}
cptPntVt = 0;
}
void printVtKmH() { //vitesse d'avancement en kilomètres / heure
uint32_t TempVtMH = vtPntMin*60*100/pnt100m;
uint32_t TempVtMHDecimal = int(TempVtMH/10 - int(TempVtMH/1000)*100);
Serial.print(int(TempVtMH/1000));
Serial.print(".");
// pour 2 décimales: if (TempVtMHDecimal < 10) {Serial.print("0");}
// pour 2 décimales: Serial.print(TempVtMHDecimal);
// pour 1 décimale:
Serial.print(TempVtMHDecimal/10);
//serial.print(" km/h");
}
void printVtMs() { //vitesse d'avancement en mètres / seconde
uint32_t TempVtCmS = vtPntMin *10000 / pnt100m /60;
uint32_t TempVtCmSDecimal = TempVtCmS - int(TempVtCmS/100)*100;
Serial.print(int(TempVtCmS/100));
Serial.print(".");
if (TempVtCmSDecimal < 10) Serial.print("0");
Serial.print(TempVtCmSDecimal);
//serial.print(" m/s");
}
void printDistMpalnter() { //>>> A adapter à la bibliothèque <<<
uint16_t TempMPlanter = nbrlignePlanteuse * cptPntDist * 100 / pnt100m;
uint16_t TempiKm = 0;
while (TempMPlanter > 999){
TempiKm ++;
TempMPlanter -= 1000;
}
TempiKm += nbrlignePlanteuse * cptPntKm;
if (TempiKm > 0){
if(TempiKm >= 1000) {
Serial.print(int(TempiKm/1000));
Serial.print("'");
Serial.print(TempiKm - int(TempiKm /1000)*1000);
}
else {
Serial.print(TempiKm);
}
Serial.print(".");
if (TempMPlanter < 100) Serial.print(0);
if (TempMPlanter < 10) Serial.print(0);
}
Serial.print(TempMPlanter);
//serial.print(" m plantés")
}
void printNbrPlants() {} //A FAIRE !
void printNbrPlantsManque() {} //A FAIRE !
bool majAlarme(){ //>>> A adapter à la bibliothèque <<<
int8_t TempCptAlarme = 0;
bool TempReponce;
if (bitRead(alarme1, 5)) TempCptAlarme +=1; //PàP trop vite
if (bitRead(alarme1, 6)) TempCptAlarme +=10; //PàP bloqué
if (bitRead(alarme1, 1)) TempCptAlarme +=5; //alarme ligne 1
if (bitRead(alarme1, 2)) TempCptAlarme +=5; //alarme ligne 2
if (bitRead(alarme1, 3)) TempCptAlarme +=5; //alarme ligne 3
if (bitRead(alarme1, 4)) TempCptAlarme +=5; //alarme ligne 4
if (TempCptAlarme == 0){ //AlarmeSTOP
bitWrite(alarme1, 0, 0);
bitClear(alarme1, 7); //BuzzerOFF
//alarmecentralBlink(false);
TempReponce = false;
}
else if (!bitRead(alarme1, 0)) { //AlarmeSTART
bitWrite(alarme1, 0, 1);
//alarmecentralBlink(true);
TempReponce = true;
}
else { //AlarmeON
//alarmecentralBlink(true);
if(TempCptAlarme > 1){
bitWrite(alarme1, 7, 1); //BuzzerON
}
TempReponce = true;
}
alarmecentral(alarme1);
return TempReponce;
}
void alarmecentral(byte AlarmeEtat) {
if (bitRead(AlarmeEtat, 0)){
if(etatAlLampe){
if (lastTimeAlBlink + 120 <= millis()){
etatAlLampe = LOW;
}
}
else {
if (lastTimeAlBlink + 200 <= millis()){
lastTimeAlBlink = millis();
etatAlLampe = HIGH;
}
}
}
else {
etatAlLampe = LOW;
//etatAlBuzzer = LOW;
}
digitalWrite(ledAlCentral, etatAlLampe);
if (bitRead(AlarmeEtat, 7)){
if(etatAlBuzz){
if (lastTimeAlBuzz + 100 <= millis()){
etatAlBuzz = LOW;
}
}
else {
if (lastTimeAlBuzz + 300 <= millis()){
lastTimeAlBuzz = millis();
etatAlBuzz = HIGH;
}
}
}
else {
etatAlBuzz = LOW;
}
digitalWrite(buzzAlCentral, etatAlBuzz);
}
void alarmeReset(){
delay(20); //Anti-rebond bloquant mais suffisant, l'action ne s'execute qu'exceptionnellement, la loop arrive à rattrapper le retard...
if (digitalRead(swAlReset)) return;
#ifdef DEBUGAlarme
Serial.print ("START_reset_alarme byte alarme1 = "); Serial.println(alarme1);
#endif
#ifdef DEBUGswitch
Serial.print("Reset alarme Start");
#endif
while (!digitalRead(swAlReset)) { } //Attend que le bouton soit relâcher pour éviter de faire le reset en boucle
// #ifdef DEBUGloopStepp_stepp >>>SAns bouton c'est normal que ça bloque !!!
// Serial.print("b"); //A_03_b
// #endif//DEBUG
for (int i = 0; i< nbrlignePlanteuse; i++){
//Old variante: alarmeResetRang(i+1);
lignePlanteuse[i]->resetAlarme();
}
alarme1 = 0;
majAlarme();
#ifdef DEBUGswitch
Serial.println("\t Reset alarme END");
#endif
#ifdef DEBUGAlarme
Serial.print ("END_reset_alarme byte alarme1 = "); Serial.println(alarme1);
#endif
delay(5);
}
void alarmeResetRang(const uint8_t nrRang){
lignePlanteuse[nrRang]->resetAlarme();
}
void manuelMoteurOn(uint16_t ManuelOnSpeed){ //active le moteur du semoir lentement (vitesse = 100step/s, accélération = 30step/s²)
delay(20); //Anti-rebond bloquant mais suffisant, la fonction s'execute à l'arrêt de la machine
if (digitalRead(swMoteurOn)) return;
#ifdef DEBUGswitch
Serial.print("manuel moteur ON");
#endif
stepper->stopMove();
while (stepper->isRunning()) { }
delay(2);
int32_t _tempStepperCurrentPos = stepper->getCurrentPosition();
uint32_t _tempStepperCurrentAccel = stepper->getAcceleration();
uint32_t _tempStepperSpeed = stepper->getSpeedInMilliHz();
stepper->setSpeedInHz(ManuelOnSpeed);
stepper->setAcceleration(30); //steps/s²
stepper->applySpeedAcceleration();
stepper->runForward();
while (!digitalRead(swMoteurOn)) { }
stepper->setAcceleration(200); //steps/s²
stepper->applySpeedAcceleration();
stepper->stopMove();
while (stepper->isRunning()) { }
delay(2);
stepper->setSpeedInMilliHz(_tempStepperSpeed);
stepper->setAcceleration(_tempStepperCurrentAccel); //steps/s²
stepper->setCurrentPosition(_tempStepperCurrentPos);
stepper->applySpeedAcceleration();
#ifdef DEBUGswitch
Serial.println("\t manuel moteur OFF");
#endif
}
void comptePnt() {
if (digitalRead(codeurAPin) == digitalRead(codeurBPin)) {
codeurPnt += valeurPnt;
}
else {
codeurPnt -= valeurPnt;
}
}
#ifdef InfoSerialMoniteur
uint32_t infoSerialMoniteurTimmer = 0;
bool infoSerialMoniteurActualiser = true;
void printInfoSerialMoniteur(){ //Affiche les information importantes sur le moniteur serie
//Afficher les valeurs actuelles de la machine
if(infoSerialMoniteurActualiser){
if(infoSerialMoniteurTimmer < millis()){ //Actualise les données toutes les 10 secondes
infoSerialMoniteurTimmer = millis() + 5000;
uint16_t _TempManqueMilleTotal = 0;
uint16_t _TempSpacePlantTotal = 0;
uint64_t _TempNbrPlanteTotal = 0;
uint64_t _TempNbrManqueTotal = 0;
for(int i = 0; i < nbrlignePlanteuse; i++){
_TempManqueMilleTotal += lignePlanteuse[i]->getManquePourMille();
_TempSpacePlantTotal += lignePlanteuse[i]->getMoyenSpacePlant();
_TempNbrPlanteTotal += lignePlanteuse[i]->getNbrPlanter();
_TempNbrManqueTotal += lignePlanteuse[i]->getNbrManquer();
}
if(_TempManqueMilleTotal > 0) _TempManqueMilleTotal = _TempManqueMilleTotal / nbrlignePlanteuse;
if(_TempSpacePlantTotal > 0) _TempSpacePlantTotal = _TempSpacePlantTotal * 100 / nbrlignePlanteuse * 100 / pnt100m; //*100 pour passer en mètre, *100 pour passer en cm / pnt100m
//1ère ligne
Serial.println("\n*** Actualisations des valeurs **********************");
Serial.print("** Vitesse: "); printVtKmH(); Serial.print("km/h");
Serial.print("\tdistance parcourue: "); printDistMpalnter(); Serial.print("km");
Serial.print("\tdistance entre plans: "); Serial.print(_TempSpacePlantTotal); Serial.print("cm");
Serial.print("\tPlanteuse active: "); if(swPlante){Serial.print("OUI");} else{Serial.print("NON");}
Serial.print("\tSemoir actif: "); if(swSeme){Serial.print("OUI");} else{Serial.print("NON");}
Serial.println();
//Ligne 2
Serial.print("** Plants manqués: "); Serial.print(int(_TempManqueMilleTotal / 10));
Serial.print("."); Serial.print(_TempManqueMilleTotal - (10 * int(_TempManqueMilleTotal / 10))); Serial.print("%");
Serial.print("\tPlants plantés: "); Serial.print(_TempNbrPlanteTotal); Serial.print("pce");
Serial.print("\tPlants manqués: "); Serial.print(_TempNbrManqueTotal); Serial.print("pce");
Serial.println("\n*********************");
// Effacer les oldALARME pour réafficher les alarme en court
oldAlarme1 = 0;
memset(oldValRangAlarme, 0, sizeof oldValRangAlarme);
}
}
//Contrôler et afficher les ALARMES
//Alarmes Rang
for(int i = 0; i < nbrlignePlanteuse; i++){
if(valRangAlarme[i] != oldValRangAlarme[i]){
if(valRangAlarme[i] <= 1){
if(oldValRangAlarme[i] > 1){ //Aficher l'extinction (la fin) d'une alarme majeure
//if(bitRead(oldValRangAlarme[i],1)) Serial.print("\n<<< Fin de l'alarme ... sur le rang "); Serial.print(i+1);
Serial.print("\n... Le rang "); Serial.print(i+1); Serial.println(" >> n'a plus d'alarme");
}
if(valRangAlarme[i] == 1){ // il y a juste un plant de manqué, c'est pas une grosse alarme
Serial.print(" , "); Serial.print(i+1); //j'affiche juste le n° du rang ou il manque un planté
} //j'affiche rien à l'extinction de cette alarme
}
else { //Une alarme importante et signalée
if(abs(valRangAlarme[i] - oldValRangAlarme[i]) > 1){ //Contrôle que pas seulement le bit1 à changé
Serial.print("\n!!! ALARME Rang "); Serial.print(i+1);
if(bitRead(valRangAlarme[i],1) << bitRead(oldValRangAlarme[i],1)) Serial.print(" ||\tmanques répétés");
if(bitRead(valRangAlarme[i],2) << bitRead(oldValRangAlarme[i],2)) Serial.print(" ||\t% manque dépassé");
if(bitRead(valRangAlarme[i],3) << bitRead(oldValRangAlarme[i],3)) Serial.print(" ||\tcapteur bloqué à ON");
if(bitRead(valRangAlarme[i],4) << bitRead(oldValRangAlarme[i],4)) Serial.print(" ||\tplants trop proche");
if(bitRead(valRangAlarme[i],5) << bitRead(oldValRangAlarme[i],5)) Serial.print(" ||\tbit5");
if(bitRead(valRangAlarme[i],6) << bitRead(oldValRangAlarme[i],6)) Serial.print(" ||\tbit6");
if(bitRead(valRangAlarme[i],7) << bitRead(oldValRangAlarme[i],7)) Serial.print(" ||\tbit7");
if(bitRead(valRangAlarme[i],1) >> bitRead(oldValRangAlarme[i],1)) Serial.print(" ..\tRésolue manques répétés");
if(bitRead(valRangAlarme[i],2) >> bitRead(oldValRangAlarme[i],2)) Serial.print(" ..\tRésolue % manque dépassé");
if(bitRead(valRangAlarme[i],3) >> bitRead(oldValRangAlarme[i],3)) Serial.print(" ..\tRésolue capteur bloqué à ON");
if(bitRead(valRangAlarme[i],4) >> bitRead(oldValRangAlarme[i],4)) Serial.print(" ..\tRésolue plants trop proche");
if(bitRead(valRangAlarme[i],5) >> bitRead(oldValRangAlarme[i],5)) Serial.print(" ..\tRésolue bit5");
if(bitRead(valRangAlarme[i],6) >> bitRead(oldValRangAlarme[i],6)) Serial.print(" ..\tRésolue tbit6");
if(bitRead(valRangAlarme[i],7) >> bitRead(oldValRangAlarme[i],7)) Serial.print(" ..\tRésolue tbit7");
Serial.println();
if(bitRead(valRangAlarme[i],0)) Serial.print(" , "); Serial.print(i+1);
}
else if(bitRead(valRangAlarme[i],0)) Serial.print(" , "); Serial.print(i+1);
}
oldValRangAlarme[i] = valRangAlarme[i];
}
}
//Alarmes semoir
if(bitRead(alarme1, 5) || bitRead(alarme1, 6)){ //Contrôler si il y a une alarme pour le semoir
if(bitRead(alarme1, 5) != bitRead(oldAlarme1, 5) || bitRead(alarme1, 6) != bitRead(oldAlarme1, 6)){ //Contrôler si elle n'a pas déjà été annoncée
Serial.print("\n>>> ALARME Semoir");
if(bitRead(alarme1, 5)) Serial.print("\t>> Vous roulez trop vite");
if(bitRead(alarme1, 6)) Serial.print("\t>> STOP le semoir est bolqué");
Serial.println();
}
}
else if(bitRead(oldAlarme1, 5) || bitRead(oldAlarme1, 6)){
Serial.print("\n... Le semoir "); Serial.println(" >> n'a plus d'alarme");
}
// bitWrite(oldAlarme1, 5, bitRead(alarme1, 5));
// bitWrite(oldAlarme1, 6, bitRead(alarme1, 6));
oldAlarme1 = alarme1;
if(alarme1 == 0){infoSerialMoniteurActualiser = true;}
else {infoSerialMoniteurActualiser = false;}
}
#endif //defined (InfoSerialMoniteur)
