mercredi 12 octobre 2016

[ARDUINO] Rotor site azimuth

Bonjour,

Aujourd'hui je vais vous montrer comment fabriquer un rotor de suivi satellite à moindre coût.

Vous aurez besoin de 2 servomoteurs de modelisme ( j'utilise des servos standard car mon rotor est prévu pour une petite antenne patch très légère), un arduino (uno, nano, mini ou juste un atmega 328 et ses 3 composants vitaux...).
Et c'est tout !

Ceux qui connaissent les servos 'classique' dirons : "Ca marchera pas, ces servos ont une course de 180°..."
C'est vrai! On trouve des servos 360° mais beaucoup plus chère, et voulant réduire les coûts, il fallait trouver une solution.

Voici la solution qui fonctionne en vidéo :
 Concrètement, et pour faire simple,
-du Nord au Sud en passant par l'Est, tout est bon avec les 180° du servo.
-lorsque qu'on passe le Sud, le servo Az fait un 180° alors que le servo de Site inverse sa position. Ce qui permet le suivi de 181° à 360°.


Coté hard, rien de compliqué : Une alim pour les servos et un arduino où l'on branchera les 2 servos (PWM 9 et 10).
Ces 2 derniers sont montés l'un sur l'autre avec quelques petites équerres. Il est possible de vous équiper d'un kit 'tilt-pan' qu'on trouve sur les drones pour bouger la caméra. Ou alors quelques pièces imprimés en 3D !

Coté software, l'arduino interprète les commandes d'un rotor au protocole Easycomm2. Il suffira donc de configurer un rotor 'easycomm2' dans votre logiciel de suivi sat préferé.
Voici la procédure sous Linux avec Gepredict :
-installer 'hamlib'
-dans un terminal : rotctld -m 901 -r /dev/ttyACM0 -s 19200
  ou -m 901 correspond au protocole Easycomm2
       -r le port série de l'Arduino (à adapter en fonction..)
       -s la vitesse du port.
-dans Gpredict:
  Edition/Préférences/Interfaces/Rotor
et ajouter un rotor comme suit :
Pour avoir accès au contrôleur de rotor, cliquer sur la flèche en haut à droite de la fenêtre de Gepredict puis "contrôle d'antenne".
Et voilà !
Le sketch de l'arduino à la fin de cet article.
Bonne bidouille !

Jérôme, F4GMU

#include <Servo.h>
Servo azServo;
Servo elServo;

char az[4];
char el[4]; 
int azInt;  
int elInt;
char inBuffer[13];
int inCount = 0;  d

char command;  
bool inBufferFull = false; 

void setup() {
 
  command = 0x00; 
 
  for (int i=0; i<4; i++){
  az[i]=0x0;
  el[i]=0x0;
  }
 

  Serial.begin(19200, SERIAL_8N1);
  azServo.attach(9);
  elServo.attach(10);
  azServo.write(0);
  elServo.write(0);
   
}

void loop() {
  
   
   
    if (command!=0x1f && command!=0x2f) return;
  
    if (command == 0x2f){
      for (int i=0;i<4;i++){   
      az[i] = inBuffer[i+1]-'0'; 
      el[i] = inBuffer[i+6]-'0';
      }
      updateAZEL();   
     
      command=0x0;   
     
      if (azInt > 180){   
        azInt=azInt-180;
        elInt=180-elInt;
      }
      azInt=azInt*(.972);
      elInt=elInt*(1);

      moveServos();
      return;                   
    }
   
    Serial.write(0x57);         
       for (int i=0; i<4; i++){
       Serial.write (az[i]);
       }
      
       Serial.write(0x01); 
      
       for (int i=0; i<4; i++){
       Serial.write(el[i]); 
        }
       
       Serial.write(0x01);     
       Serial.write(0x20);      /
       command=0x0;
}




//--------------------------------------------------------------

void updateAZEL() {
 
  elInt=0;
  azInt=0;
 
  azInt = az[1]*100;         
  azInt = azInt + az[2]*10;
  azInt = azInt + az[3];
 
  elInt = el[1]*100;
  elInt = elInt + el[2]*10;
  elInt = elInt + el[3];
 
  if (azInt >= 360) azInt=azInt-360; 

  char buf[3];
 
  sprintf (buf, "%03i", azInt);
  for (int i = 0; i<3;i++){
    az[i] = buf[i]- '0';
  }
 
  sprintf (buf, "%03i", elInt);
  for (int i = 0; i<3;i++){
    el[i] = buf[i]- '0';
  }
 
  az[3]=0;
  el[3]=0;
 
  if (elInt >= 360) elInt=elInt-360;  //
}

//--------------------------------------------------------------

void serialEvent(){

  while (Serial.available()){
 
    char inChar= (char) Serial.read();
      inBuffer[inCount]=inChar;
      inCount++;
     
  }
 
  if (inCount==13){
    command=inBuffer[11];

    inCount=0;
  }
}



//--------------------------------------------------------------

void moveServos(){

  azServo.write(azInt);
  elServo.write(elInt);
}

6 commentaires:

  1. Super, bravo et merci pour ton article Jérôme

    RépondreSupprimer
  2. Hello D'jé , comme d'habitude une superbe bidouille !!!! A très bientôt et merci pour le partage !!! F1OLG

    RépondreSupprimer
    Réponses
    1. Merci Thierry, à bientôt pour d'autres bidouilles ;)

      Supprimer
  3. Bonjour Jérôme,
    je suis très intéressé par ce projet et j'aimerai marcher sur vos pas et realisé ce projet à mon tour ... Pourriez vous m'indiquer comment faut il s'y prendre pour calibrer les servos s'il vous plait ? Quelles positions initiales faut il leur donner (c'est à dire comment fixer physiquement le "zero" ) ? Merci beaucoup pour ce site, vos idées et votre patience ;-) ... Excellente journée

    RépondreSupprimer
    Réponses
    1. Bonjour et merci pour ton commentaire.
      La position initiale de se rotor est le Nord, 0° d'élévation (0° site, 0°azimunth).
      Dans cette position, les servos (180°) sont en butée CCW si mes souvenirs sont bon (je n'utilise plus ce montage). Mais une chose est sûr, il sont en buté d'un coté.
      Tu auras vite fais de trouver le sens une fois l'arduino branché ;)
      Bonne bidouille,
      Jérôme.

      Supprimer