Bonjour,
Je suis débutant en arduino (mais pas en programmation). Je suis en train de tester un systeme qui me permettrait d'indiquer les coordonnées d'un astre visé avec un télescope. Dans ce but j'ai mis en place un Arduino Mega 2560 que j'avais sous la main et j'ai réussi à récupérer 2 encodeurs rotatif de la marque Sick qui ont 10000 pas par tour, soit un resolution d'environ 2 Arcminute par impulsion
Voici les encodeurs: DFS60B-S1PK10000 | Codeurs | SICK
Le but est donc de me donner l'angle horizontale (Azimut) et l'angle vertical (Altitude). J'ai donc Ecrit un bout de code classique pour des encodeurs avec gestion des impulsions par interruption. Ça ne marche pas trop mal si je tourne très doucement mais dès que j'accélère, je perd vraiment beaucoup d'impulsion (jusqu'à 50% si je tourne très vite).
Quelle est la cause de ce phénomène: Encodeurs trop précis et/ Arduino trop lent? ou un problème de code (que je joins ci dessous)? Y-a-t-il une solution pour régler ce soucis ou tout au moins le réduire de façon conséquente. Pour ceux qui connaissent, le télescope est un Dobson, donc tourner à la main.
// CONSTANTES
#define ENC_AZIM_A 2 // Port signal A encodeur Azimut
#define ENC_AZIM_B 22 // Port signal B encodeur Azimut
#define NB_IMP_ENC 10000.0 // Nb impulsions par tour encodeur
#define ENC_ALTI_A 3 // Port signal A encodeur Altitude
#define ENC_ALTI_B 23 // Port signal B encodeur Altitudeaison
#define SEC_PAR_TR 360.0*60*60 // Nbre d'Arseconde par tour
#define INC_SEC SEC_PAR_TR/NB_IMP_ENC // Angle en Arcseconde par pas de l'encodeur
// VARIABLES GLOBALES
volatile long ComptImpAzim; // Compteur d'impulsions en Azimut
volatile long ComptImpAlti; // Compteur d'impulsions en Altitude
unsigned long AncienMillis; // Pour tempo non bloquante
// PROTO FONCTIONS
char *arcsec2str( double arcsec);
void Move_Azim();
void Move_Alti();
// Récupération des mouvements de l'azimut
void Move_Azim()
{
if (digitalRead(ENC_AZIM_B))
ComptImpAzim--;
if (ComptImpAzim < 0) ComptImpAzim += NB_IMP_ENC;
else
ComptImpAzim++;
if (ComptImpAzim >= NB_IMP_ENC) ComptImpAzim -= NB_IMP_ENC;
}
// Récupération des mouvements de l'altitude
void Move_Alti()
{
if (digitalRead(ENC_ALTI_B))
ComptImpAlti--;
if (ComptImpAlti < 0) ComptImpAlti += NB_IMP_ENC;
else
ComptImpAlti++;
if (ComptImpAlti >= NB_IMP_ENC) ComptImpAlti -= NB_IMP_ENC;
}
// Transforme l'angle en arcsec vers une chaine [+ddd° mm' ss.ss"]
char *arcsec2str(double arsec )
{
int degre;
int minute;
double seconde;
static char rep[20];
char secch[5];
char minch[2];
degre = int(arsec/3600);
minute = int((arsec - (degre*3600)) /60);
seconde = (arsec - (degre*3600) - (minute*60));
dtostrf(seconde, 5, 2, secch);
dtostrf(minute, 2, 0, minch);
//
sprintf(rep,"%4d° %s' %s""",degre, minch, secch);
return rep;
}
void setup()
{
// Pin A et B encodeur Az en entrée
pinMode(ENC_AZIM_A, INPUT);
pinMode(ENC_AZIM_B, INPUT);
// Pin A et B encodeur AltC en entrée
pinMode(ENC_ALTI_A, INPUT);
pinMode(ENC_ALTI_B, INPUT);
// Pull up
digitalWrite(ENC_AZIM_A, HIGH);
digitalWrite(ENC_AZIM_B, HIGH);
digitalWrite(ENC_ALTI_A, HIGH);
digitalWrite(ENC_ALTI_B, HIGH);
// Init port série 0 pour moniteur
Serial.begin (9600);
// Init à 0 des compteurs d'impulsions
ComptImpAzim = 0;
ComptImpAlti = 0;
// Detection des mouvements d'encodeurs par interruption sur front descendant sur signal A
attachInterrupt(digitalPinToInterrupt(ENC_AZIM_A), Move_Azim, FALLING);
attachInterrupt(digitalPinToInterrupt(ENC_ALTI_A), Move_Alti, FALLING);
}
void loop()
{
float Ang_Azim;
float Ang_Alti;
AncienMillis = millis();
// Affichage des angles toutes les 500ms sans blocage
if ( (millis() - AncienMillis) > 500) {
// Angle d'azimut
Ang_Azim = ComptImpAzim*INC_SEC;
Serial.print("Azim: ");
Serial.print(arcsec2str(Ang_Azim));
// Angle d'azimut
Ang_Alti = ComptImpAlti*INC_SEC;
Serial.print(" - Alt: ");
Serial.print(arcsec2str(Ang_Alti));
AncienMillis = millis();
}
/*
* AUTRES TRAITEMENTS ET CALCUL FAIT ICI
* Avec des tempo non bloquantes (millis())
*
*
*/
}
Je vous remercie d'avance de l'aide que vous voudrez bien m'apporter.
Anthony.