Plop les maker's, bon ben quiche un jour quiche toujours, voilà, j'arrive donc à gérer la vitesse de mes servomoteurs avec la boucle while et millis(), le truc, c'est que cela s'execute servo par servo et non tout en même temps, normal, le while bloquant le code ça le fait pas, je post donc mon code espérant un peu plus de vos lumières les gars ^^
Je colle le principal hein, si ils vous manquent quelque chose je le rajouterai.
Dans les grandes lignes, le temps s'écoule avec millis() et j'essaye de gérer ma vitesse en donnant une position à atteindre et le temps nécessaire pour y arriver.
Arduino com (main)
// J'ai viré la partie E-paper pour que cela soit plus "lisible" #include "TimerOne.h" //Lib pour la communication entre la Pi et Arduino //-----GcomA #include "GcomA.h" //-----end GcomA //-----VL53L0x #include <Wire.h> #include <VL53L0X.h> VL53L0X sensor; unsigned int readVl5310x; //-----end VL53L0x Servo servo0(0); Servo servo1(1); Servo servo2(2);// je ne me sers que de celui ci pour tester void setup(){ Serial.begin (115200); Serial1.begin(115200); //Convertisseur logique Serial2.begin(115200); //Driver Pololu Maestro servoZero(); //On initialise les servo à 0 //-----Timer Timer1.initialize(1000); Timer1.attachInterrupt(timerIsr); //-----end Timer //-----VL53L0x Wire.begin(); sensor.init(); sensor.setTimeout(300); sensor.startContinuous(0); //Continuous //sensor.setMeasurementTimingBudget(600000); // 200 ms Single //-----end VL53L0x } void loop() { //-----VL53L0x readVl5310x = sensor.readRangeContinuousMillimeters(); if (sensor.timeoutOccurred()) { Serial.print(" TIMEOUT"); } //----- arduinoReceive(); servo2.updateServo(); } void timerIsr() { servo2.moveServo();}
Arduino GcomA.cpp (ouais je n'ai pas encore séparé la partie servomoteur de la communication)
Donc une partie du code, la partie de mon problème.
#include <Arduino.h>#include "GcomA.h" //#include "TimerOne.h" //-----Driver Maestro Pololu #include <PololuMaestro.h> MiniMaestro maestro(Serial2); //----- #define NB_SERVO 5 /* * DMIN Degré minimum du servo * DMAX Degré maximum du servo * IMIN Impulsion minimum du servo * IMAX Impulsion maximum du servo */ //Servo HV5932 - 1984 - 9984 //Tête #define DMIN0 -90 #define DMAX0 90 #define IMIN0 1920 #define IMAX0 9500 #define DMIN1 -90 #define DMAX1 90 #define IMIN1 1920 #define IMAX1 9500 #define DMIN2 -90 #define DMAX2 90 #define IMIN2 1920 #define IMAX2 9500 #define DMIN3 -90 #define DMAX3 90 #define IMIN3 1920 #define IMAX3 9500 #define DMIN4 -90 #define DMAX4 90 #define IMIN4 1920 #define IMAX4 9500 //Structure pour l'affichage sur E-PAPER struct S_EPAPER { char ms_msg[20]; }; //Structure pour l'émission de données vers la PI struct S_PI { int ms_roll; //2 octet/bytes (16 bits) : -32 768 / +32 767 int ms_pitch; //2 octet/bytes (16 bits) : -32 768 / +32 767 int ms_yaw; //2 octet/bytes (16 bits) : -32 768 / +32 767 unsigned int ms_boussole; //2 octet/bytes (8 bits) : 0 / 65 535 unsigned int ms_vl53l0x; //2 octet/bytes (8 bits) : 0 / 65 535 }; //Structure pour la récepetion des données des servomoteurs venant de la pi, ça transit ici. struct S_SERVO { unsigned int ms_servo; unsigned int ms_time; //2 octet/bytes (8 bits) : 0 / 65 535 int ms_cible; //2 octet/bytes (16 bits) : -32 768 / +32 767 }; //On copie ici ce que l'on a reçu de la pi avec une imbrication de structure, Mike me dis pas que c'est pas bien sinon ça va gueuler PTDR (humour) //On retrouve donc toutes les infos min et max en degrés et en impulsion et on rajoute pour chaque servo les infos venant de la Pi. struct S_SERVODATA { int ms_Dmin; //Degré minimum du servo int ms_Dmax; //Degré maximum du servo unsigned int ms_Imin; //Impulsion minimum du servo unsigned int ms_Imax; //Impulsion maximum du servo int ms_posInitiale; //Position initiale du servo int ms_posFinale; //Position finale du servo //Imbrication de structure S_SERVO s_servoInfo; //Infos du servo envoyé par la PI et copié dans la structure adéquat s_servoInfo }; //Union pour envoyer nos types struct dans un tableau unsigned char union U_DATA { S_PI s_pi; S_SERVO s_servo[NB_SERVO]; S_EPAPER s_epaper; //L'envoie et la réception sont dans des tableaux //(sizeof) permet de récupérer la taille en byte de nos structures unsigned char cast_servo[sizeof s_servo]; unsigned char cast_pi[sizeof s_pi]; unsigned char cast_epaper[sizeof s_epaper]; }u_servo, u_pi, u_buf, u_epaper; //incomingByte & incomingEpaper initialisée pour tester l'entrée de données int incomingByte = 0; int incomingEpaper = 0; int rollData = 0; int pitchData = 0; int yawData = 0; unsigned int boussoleData = 0; //byte j = 0; //On initialise chaque servo avec ces données respectives S_SERVODATA s_servoData[NB_SERVO] = {{DMIN0, DMAX0, IMIN0, IMAX0, 0, 0} ,{DMIN1, DMAX1, IMIN1, IMAX1, 0, 0} ,{DMIN2, DMAX2, IMIN2, IMAX2, 0, 0} ,{DMIN3, DMAX3, IMIN3, IMAX3, 0, 0} ,{DMIN4, DMAX4, IMIN4, IMAX4, 0, 0}}; //----- unsigned long timeReference = 0; unsigned long timeServoFinal = 0; //-----Timer Timer1.initialize(1000); // set a timer of length 1000 microseconds = 1 ms - or 1000Hz Timer1.attachInterrupt( timerIsr ); //-----end Timer //-----On envoie les données des capteurs à la Pi void arduinoSend(unsigned int readVl5310x){ unsigned int waitingTime = 100; // 0.100 secondes unsigned long refTime = 0; u_pi.s_pi.ms_vl53l0x = readVl5310x; Serial1.write (u_pi.cast_pi, sizeof u_buf.cast_pi); //Gestion de temps waitingTime en ms refTime = millis(); //Début de l'attente : while((millis()-refTime)<waitingTime){ //attend } } //On recoit les données de la Pi void arduinoReceive() { if (Serial1.available() == sizeof u_servo.cast_servo) { incomingByte = Serial1.readBytes (u_servo.cast_servo, sizeof u_servo.cast_servo); for (byte i = 0; i < NB_SERVO; i++) { s_servoData[i].s_servoInfo = u_servo.s_servo[i]; } } } Servo::Servo(byte servo) { i = servo; // <--------------il est là le i pour la class ^^ } void Servo::setTime() //j'ai l'impression que cette fonction ne sert à rien en fait { previousTime = 0;//millis(); lastUpdate = 0; } void Servo::moveServo() { if ((millis()-timeReference) < s_servoData[i].s_servoInfo.ms_time) { deltaTime = millis(); deltaPosition = map(deltaTime, timeReference, timeServoFinal, s_servoData[i].ms_posInitiale, s_servoData[i].s_servoInfo.ms_cible);//s_servoData[i].ms_posFinale); angle = map(deltaPosition, s_servoData[i].ms_Dmin, s_servoData[i].ms_Dmax, s_servoData[i].ms_Imin, s_servoData[i].ms_Imax); maestro.setTarget(s_servoData[i].s_servoInfo.ms_servo, angle); } else { angle = map(s_servoData[i].s_servoInfo.ms_cible, s_servoData[i].ms_Dmin, s_servoData[i].ms_Dmax, s_servoData[i].ms_Imin, s_servoData[i].ms_Imax); maestro.setTarget(s_servoData[i].s_servoInfo.ms_servo, angle); } s_servoData[i].ms_posInitiale = u_servo.s_servo[i].ms_cible; } void Servo::updateServo() { if (u_servo.s_servo[i].ms_servo == u_servo.s_servo[i].ms_cible) { Serial.println (":: Si la position est la même, ne fais rien.... ::"); } else { s_servoData[i].ms_posInitiale = u_servo.s_servo[i].ms_cible; u_servo.s_servo[i].ms_cible = u_servo.s_servo[i].ms_servo; //position_commande; timeReference = millis(); timeServoFinal = timeReference + s_servoData[i].s_servoInfo.ms_time; } } /* void Servo::timerIsr() { moveServo(); } */ void servoZero () { for (int i = 0; i < NB_SERVO; i++) { maestro.setTarget(i, 5952); } }